<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Posts on Christian Gmeiner</title>
    <link>https://christian-gmeiner.info/posts/</link>
    <description>Recent content in Posts on Christian Gmeiner</description>
    <image>
      <title>Christian Gmeiner</title>
      <url>https://christian-gmeiner.info/papermod-cover.png</url>
      <link>https://christian-gmeiner.info/papermod-cover.png</link>
    </image>
    <generator>Hugo -- 0.159.0</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 19 Jun 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://christian-gmeiner.info/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>The Diagonal Seam</title>
      <link>https://christian-gmeiner.info/2026-06-19-the-diagonal-seam/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2026-06-19-the-diagonal-seam/</guid>
      <description>&lt;p&gt;Two more dEQP tests down:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_mag -- Pass
dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_min -- Pass
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This one was a fun geometry puzzle.&lt;/p&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;
&lt;p&gt;Mesa&amp;rsquo;s &lt;code&gt;u_blitter&lt;/code&gt; is the utility that drivers use for framebuffer blits &amp;ndash; copying pixel data between surfaces, optionally scaling and filtering. It works by drawing a textured quad: set up the source as a texture, the destination as a render target, and draw a rectangle with the appropriate texture coordinates. Simple.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Two more dEQP tests down:</p>
<pre tabindex="0"><code>dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_mag -- Pass
dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_min -- Pass
</code></pre><p>This one was a fun geometry puzzle.</p>
<h2 id="the-problem">The problem</h2>
<p>Mesa&rsquo;s <code>u_blitter</code> is the utility that drivers use for framebuffer blits &ndash; copying pixel data between surfaces, optionally scaling and filtering. It works by drawing a textured quad: set up the source as a texture, the destination as a render target, and draw a rectangle with the appropriate texture coordinates. Simple.</p>
<p>Except the quad is made of two triangles. And that diagonal seam between them is where the trouble starts.</p>
<pre tabindex="0"><code> v2 -------- v3
  |  \   T2  |
  | T1  \    |
  |       \  |
 v0 -------- v1
</code></pre><p>For LINEAR filtering, this is fine &ndash; the interpolation across the seam is smooth enough that nobody notices. But for NEAREST filtering, a texel is selected based on which texel center is closest to the interpolated texture coordinate. At the diagonal seam, the two triangles can produce <em>slightly different</em> texture coordinates for pixels that sit right on the boundary. Different coordinates mean different nearest-texel selection, and that means an inconsistent stripe of wrong texels running diagonally across the blit.</p>
<p>The dEQP <code>nearest_consistency</code> tests specifically check for this: they blit with NEAREST filtering and verify that every pixel picks the same texel regardless of which triangle it fell into.</p>
<p><img alt="tags" loading="lazy" src="/img/diagonal-seam.png"></p>
<h2 id="what-others-do">What others do</h2>
<p>This isn&rsquo;t a new problem. V3D already has a workaround in <code>u_blitter</code>: it sets <code>use_index_buffer</code> to reorder the triangle indices so that the shared edge of the two triangles is along a different diagonal. This changes which pixels land on the seam and can be enough to pass the tests on some hardware.</p>
<p>On GC7000, that wasn&rsquo;t sufficient. The floating-point interpolation differences are large enough that the seam remains visible regardless of which diagonal you pick.</p>
<h2 id="what-the-blob-does">What the blob does</h2>
<p>Looking at command stream traces from the proprietary Vivante driver, the answer was clear: they don&rsquo;t draw a quad at all. They draw a <strong>single oversized triangle</strong> and let the scissor clip it to the destination rectangle.</p>
<p>No seam, no problem.</p>
<h2 id="the-single-triangle-transform">The single triangle transform</h2>
<p>The idea is simple: take a rectangle and find a single triangle that fully covers it. The smallest such triangle is a right triangle with legs twice the width and twice the height of the rectangle:</p>
<pre tabindex="0"><code> v2
  |\
  |  \
  | rect\
  |------+\
  |      |  \
 v0 -----|--- v1
</code></pre><p>Vertex 0 stays at the rectangle&rsquo;s top-left corner. Vertex 1 extends to twice the rectangle width. Vertex 2 extends to twice the rectangle height. The original rectangle is fully contained within this triangle.</p>
<p>The math for transforming the blitter&rsquo;s 4-vertex quad into a 3-vertex triangle is:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">a</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">a</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">;</span> <span class="n">a</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>      <span class="cm">/* pos and texcoord */</span>
</span></span><span class="line"><span class="cl">   <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">c</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">c</span> <span class="o">&lt;</span> <span class="mi">4</span><span class="p">;</span> <span class="n">c</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>   <span class="cm">/* xyzw components */</span>
</span></span><span class="line"><span class="cl">      <span class="kt">float</span> <span class="n">v0</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">-&gt;</span><span class="n">vertices</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">a</span><span class="p">][</span><span class="n">c</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">      <span class="n">ctx</span><span class="o">-&gt;</span><span class="n">vertices</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="n">a</span><span class="p">][</span><span class="n">c</span><span class="p">]</span> <span class="o">=</span> <span class="mf">2.0f</span> <span class="o">*</span> <span class="n">ctx</span><span class="o">-&gt;</span><span class="n">vertices</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="n">a</span><span class="p">][</span><span class="n">c</span><span class="p">]</span> <span class="o">-</span> <span class="n">v0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="n">ctx</span><span class="o">-&gt;</span><span class="n">vertices</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="n">a</span><span class="p">][</span><span class="n">c</span><span class="p">]</span> <span class="o">=</span> <span class="mf">2.0f</span> <span class="o">*</span> <span class="n">ctx</span><span class="o">-&gt;</span><span class="n">vertices</span><span class="p">[</span><span class="mi">3</span><span class="p">][</span><span class="n">a</span><span class="p">][</span><span class="n">c</span><span class="p">]</span> <span class="o">-</span> <span class="n">v0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">   <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This transforms both position and texture coordinates consistently, so the texture mapping across the visible (scissored) region is identical to what the full quad would have produced &ndash; minus the seam.</p>
<h2 id="scissor-is-essential">Scissor is essential</h2>
<p>The oversized triangle extends beyond the destination rectangle, so we need scissor to clip it. The blitter doesn&rsquo;t always have a scissor set up, so when <code>use_single_triangle</code> is enabled, we synthesize one from the destination box:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="n">ctx</span><span class="o">-&gt;</span><span class="n">base</span><span class="p">.</span><span class="n">use_single_triangle</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">scissor</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">   <span class="n">synth_scissor</span><span class="p">.</span><span class="n">minx</span> <span class="o">=</span> <span class="nf">MAX2</span><span class="p">(</span><span class="n">dstbox</span><span class="o">-&gt;</span><span class="n">x</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">   <span class="n">synth_scissor</span><span class="p">.</span><span class="n">miny</span> <span class="o">=</span> <span class="nf">MAX2</span><span class="p">(</span><span class="n">dstbox</span><span class="o">-&gt;</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">   <span class="n">synth_scissor</span><span class="p">.</span><span class="n">maxx</span> <span class="o">=</span> <span class="n">dstbox</span><span class="o">-&gt;</span><span class="n">x</span> <span class="o">+</span> <span class="n">dstbox</span><span class="o">-&gt;</span><span class="n">width</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">   <span class="n">synth_scissor</span><span class="p">.</span><span class="n">maxy</span> <span class="o">=</span> <span class="n">dstbox</span><span class="o">-&gt;</span><span class="n">y</span> <span class="o">+</span> <span class="n">dstbox</span><span class="o">-&gt;</span><span class="n">height</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">   <span class="n">scissor</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">synth_scissor</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h2 id="keeping-it-scoped">Keeping it scoped</h2>
<p>The single-triangle transform should only apply to blit operations, not to clears or other blitter draws. A transient <code>single_triangle_active</code> flag is set around the actual blit draw calls and checked in the vertex emission code. Drivers opt in by setting <code>use_single_triangle</code> on the blitter context at creation time.</p>
<p>For etnaviv, that&rsquo;s a single line:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">ctx</span><span class="o">-&gt;</span><span class="n">blitter</span><span class="o">-&gt;</span><span class="n">use_single_triangle</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
</span></span></code></pre></div><h2 id="the-design">The design</h2>
<p>The implementation is split into two commits: the <code>u_blitter.c</code> infrastructure (vertex transform, synthesized scissor, gating flag, 3-vertex draw path) that any driver can opt into, and the one-line etnaviv enablement. Keeping them separate means another driver hitting the same seam can flip the flag without touching u_blitter code.</p>
<p>The work landed upstream in <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39973">u_blitter: Add single-triangle draw mode for NEAREST blit consistency</a>.</p>
<h2 id="the-takeaway">The takeaway</h2>
<p>Sometimes the fix for a rendering artifact isn&rsquo;t better math or tighter tolerances &ndash; it&rsquo;s removing the geometric feature that causes the problem in the first place. Two triangles have a seam. One triangle doesn&rsquo;t.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Fixing the R/B swap the right way</title>
      <link>https://christian-gmeiner.info/2026-06-10-fixing-the-rb-swap-the-right-way/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2026-06-10-fixing-the-rb-swap-the-right-way/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;ve ever looked at a GPU render and seen blue where red should be, you&amp;rsquo;ve met the R/B swap problem. For etnaviv this has been a long-standing source of complexity. We were solving it in the shader, but the proprietary blob driver had a simpler approach all along. As part of my work at &lt;a href=&#34;https://www.igalia.com/&#34;&gt;Igalia&lt;/a&gt;, I finally sat down and did it properly.&lt;/p&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;
&lt;p&gt;Vivante GPUs have a quirk: the Pixel Engine (PE) always writes pixels in BGRA byte order. When your API says &amp;ldquo;render to R8G8B8A8_UNORM&amp;rdquo;, what actually lands in memory is B, G, R, A. Every byte of every pixel, every frame. The hardware just works that way.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>If you&rsquo;ve ever looked at a GPU render and seen blue where red should be, you&rsquo;ve met the R/B swap problem. For etnaviv this has been a long-standing source of complexity. We were solving it in the shader, but the proprietary blob driver had a simpler approach all along. As part of my work at <a href="https://www.igalia.com/">Igalia</a>, I finally sat down and did it properly.</p>
<h2 id="the-problem">The problem</h2>
<p>Vivante GPUs have a quirk: the Pixel Engine (PE) always writes pixels in BGRA byte order. When your API says &ldquo;render to R8G8B8A8_UNORM&rdquo;, what actually lands in memory is B, G, R, A. Every byte of every pixel, every frame. The hardware just works that way.</p>
<p>The question is: where do you fix it?</p>
<p>The etnaviv driver was doing it in the shader. Before the fragment shader writes its output, a <a href="https://docs.mesa3d.org/nir/index.html">NIR</a> lowering pass swaps the R and B channels:</p>
<pre tabindex="0"><code>   alu-&gt;src[0].swizzle[0] = 2;   /* .r reads from .b */
   alu-&gt;src[0].swizzle[2] = 0;   /* .b reads from .r */
</code></pre><p>This works, until it doesn&rsquo;t. The shader key needs a <code>frag_rb_swap</code> bitmask per render target. The blend color needs per-RT R/B swapping to match. And it falls apart entirely for scalar outputs - if a shader writes a single float, there&rsquo;s no <code>.z</code> component to swizzle into <code>.x</code>. That&rsquo;s exactly the NIR validation failure we hit:</p>
<pre tabindex="0"><code>Test case &#39;dEQP-GLES3.functional.fragment_out.basic.fixed.rgb8_lowp_float&#39;..
NIR validation failed after etna_lower_io in ../mesa/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c:1296
1 errors:
shader: MESA_SHADER_FRAGMENT
source_blake3: {0x4d463d73, 0x4b27d742, 0x27a92b64, 0x375c010f, 0xb2ce3767, 0x2adc55cc, 0x6da8105b, 0x5b9fce29}
name: GLSL1
prev_stage: MESA_SHADER_VERTEX
inputs_read: 32
outputs_written: 4
perspective_varyings: 32
max_subgroup_size: 128
min_subgroup_size: 1
api_subgroup_size_draw_uniform: true
first_ubo_is_default_ubo: true
known_interpolation_qualifiers: true
flrp_lowered: true
inputs: 1
outputs: 1
decl_var shader_in INTERP_MODE_SMOOTH none highp float packed:var0 (VARYING_SLOT_VAR0.x, 0, 0)
decl_var shader_out INTERP_MODE_NONE none mediump float out0 (FRAG_RESULT_DATA0.x, 0, 0)
decl_function main () (entrypoint)

impl main {
    block b0:  // preds:
    32    %3 = load_const (0x00000000)
    32    %4 = @load_input (%3 (0x0)) (base=0, range=1, component=0, dest_type=float32, io location=VARYING_SLOT_VAR0 slots=1)  // packed:var0
    32    %2 = deref_var &amp;out0 (shader_out mediump float)
    32    %5 = mov %4.z
error: src-&gt;swizzle[i] &lt; num_components (../mesa/src/compiler/nir/nir_validate.c:217)

               @store_deref (%2, %5) (wrmask=x, access=none)
               // succs: b1
    block b1:
}

FATAL ERROR: Test program crashed
</code></pre><h2 id="what-the-blob-does">What the blob does</h2>
<p>Looking at command stream traces from the proprietary driver, the answer is almost disappointingly simple. Instead of this:</p>
<pre tabindex="0"><code>  Texture format: A8B8G8R8     (read BGRA as BGRA)
  PE format:      A8B8G8R8     (write BGRA)
  Shader:         swap R &lt;-&gt; B
</code></pre><p>The blob does this:</p>
<pre tabindex="0"><code>  Texture format: A8R8G8B8     (read BGRA as RGBA - hardware swaps on read)
  PE format:      A8B8G8R8     (write BGRA - unchanged)
  Shader:         nothing
</code></pre><p>That&rsquo;s it. Tell the texture sampler the data is A8R8G8B8, and it will correctly interpret the BGRA bytes as RGBA channels. The PE keeps writing BGRA because that&rsquo;s what it does. No shader modification needed.</p>
<p>In our format table, the change is a single field:</p>
<pre tabindex="0"><code>  -  VT(R8G8B8A8_UNORM, UNSIGNED_BYTE, A8B8G8R8, A8B8G8R8)
  +  VT(R8G8B8A8_UNORM, UNSIGNED_BYTE, A8R8G8B8, A8B8G8R8)
                                        ^^^^^^^^
                                     texture format
</code></pre><h2 id="the-data-flow">The data flow</h2>
<p>To understand why this works, trace a red pixel through the pipeline:</p>
<pre tabindex="0"><code>                          BGRA-internal byte order
                         +------------------------+
                         |                        |
  API: glClear(1,0,0,1)  |   Memory: [0,0,255,255]|   CPU: expects [255,0,0,255]
  &#34;red = 1.0&#34;            |   (B=0, G=0, R=255,    |   &#34;RGBA order&#34;
                         |    A=255)              |
                         +------------------------+

  +-----------+     +--------+     +--------+     +---------+
  | Shader    |     | PE     |     | Memory |     | Sampler |
  | out=RGBA  | --&gt; | writes | --&gt; | stores | --&gt; | reads   |
  | (1,0,0,1) |     | BGRA   |     | BGRA   |     | as      |
  |           |     |        |     | bytes  |     | A8R8G8B8|
  +-----------+     +--------+     +--------+     +---------+
       |                |               |              |
    R=1.0            B=0x00          [00 00 FF FF]   R=1.0
    G=0.0            G=0x00                          G=0.0
    B=0.0            R=0xFF                          B=0.0
    A=1.0            A=0xFF                          A=1.0
</code></pre><p>The shader writes (1,0,0,1). The PE swaps R/B on write, so memory gets [0,0,255,255] in BGRA order. The sampler, told the format is A8R8G8B8, reads those same bytes back as (1,0,0,1). Round-trip complete, no shader involvement.</p>
<h2 id="the-cpu-boundary-problem">The CPU boundary problem</h2>
<p>GPU-to-GPU is clean. But what happens at the CPU boundary - <code>glReadPixels</code>, <code>glTexSubImage</code>, <code>glBlitFramebuffer</code> to a CPU-mapped buffer? The CPU expects RGBA byte order. Memory has BGRA. Something needs to swap.</p>
<p>This is where the hardware copy/resolve engines come in - <code>RS</code> and <code>BLT</code>. Both can perform R/B swapping during their copy operations. The RS engine has a <code>swap_rb</code> bit. The BLT engine has per-side swizzle fields. We just need to activate this at the right moment.</p>
<p>The key insight: only transfer blits (tiled-to-linear copies for CPU access) need the swap. GPU-internal blits - glBlitFramebuffer between two render targets, TS resolve, mipmap generation - are all operating on data already in BGRA order on both sides. Swapping there would be wrong.</p>
<p>So we gate it with a context flag:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">ctx</span><span class="o">-&gt;</span><span class="n">in_transfer_blit</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="nf">etna_copy_resource_box</span><span class="p">(</span><span class="n">pctx</span><span class="p">,</span> <span class="n">trans</span><span class="o">-&gt;</span><span class="n">rsc</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">rsc</span><span class="o">-&gt;</span><span class="n">base</span><span class="p">,</span> <span class="p">...);</span>
</span></span><span class="line"><span class="cl"><span class="n">ctx</span><span class="o">-&gt;</span><span class="n">in_transfer_blit</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
</span></span></code></pre></div><p>And in the RS blit path:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="p">.</span><span class="n">swap_rb</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">-&gt;</span><span class="n">in_transfer_blit</span> <span class="o">&amp;&amp;</span>
</span></span><span class="line"><span class="cl">           <span class="nf">translate_pe_format_rb_swap</span><span class="p">(</span><span class="n">blit_info</span><span class="o">-&gt;</span><span class="n">src</span><span class="p">.</span><span class="n">format</span><span class="p">),</span>
</span></span></code></pre></div><h2 id="the-texture-shadow-trap">The texture shadow trap</h2>
<p>With the basic approach working, tests passed on GC7000 (BLT engine). But GC2000 (RS engine) had a regression: <code>fbo-blit</code> showed blue where red should be.</p>
<p>After adding debug prints and tracing the code paths, the culprit was the texture shadow. Some resources can&rsquo;t be sampled directly by the texture unit - for example, a render target might use a layout the sampler doesn&rsquo;t understand. For these, the driver allocates a second copy of the resource in a sampler-compatible tiled layout. This is the &ldquo;texture shadow&rdquo;.</p>
<p>The shadow is a workaround that hurts performance - it means extra memory and extra copies. Ideally we wouldn&rsquo;t need it at all. But while it exists, the driver uses it as a shortcut for CPU transfers: read directly from the shadow and detile in software, skipping the blit engine:</p>
<pre tabindex="0"><code>Passing probes:  PATH=temp_resource+RS_blit    swap_rb=1   -&gt; correct
Failing probes:  PATH=texture_shadow                       -&gt; R/B swapped
</code></pre><p>The texture shadow path does a software detile - raw byte copy, no R/B swap. With BGRA-internal byte order, that gives you BGRA bytes on the CPU side. Wrong.</p>
<p>The fix: skip the texture shadow shortcut for formats that need R/B swap, forcing through the blit engine path which handles the conversion:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="n">rsc</span><span class="o">-&gt;</span><span class="n">texture</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nf">etna_resource_newer</span><span class="p">(</span><span class="n">rsc</span><span class="p">,</span> <span class="nf">etna_resource</span><span class="p">(</span><span class="n">rsc</span><span class="o">-&gt;</span><span class="n">texture</span><span class="p">))</span> <span class="o">&amp;&amp;</span>
</span></span><span class="line"><span class="cl">    <span class="o">!</span><span class="nf">translate_pe_format_rb_swap</span><span class="p">(</span><span class="n">prsc</span><span class="o">-&gt;</span><span class="n">format</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">   <span class="cm">/* Use texture shadow - safe, no R/B swap needed */</span>
</span></span><span class="line"><span class="cl">   <span class="n">rsc</span> <span class="o">=</span> <span class="nf">etna_resource</span><span class="p">(</span><span class="n">rsc</span><span class="o">-&gt;</span><span class="n">texture</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">   <span class="cm">/* Use blit engine - handles R/B swap correctly */</span>
</span></span><span class="line"><span class="cl">   <span class="p">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h2 id="results">Results</h2>
<p>This is a net-negative patch series - 15 files changed, 76 insertions, 113 deletions. The <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38710">etnaviv: Remove RB swap logic in the fragment shader</a> contains all that&rsquo;s needed:</p>
<ol>
<li><strong>blt: Use img-&gt;swizzle for CONFIG SWIZ fields</strong> - preparation for per-image swizzle support</li>
<li><strong>Add translate_pe_internal_format helper</strong> - maps RGBA pipe formats to BGRA equivalents for clear color packing</li>
<li><strong>Use BGRA-internal texture format with BLT/RS R/B swizzle</strong> - the main change</li>
<li><strong>Compute blend color directly in etna_set_blend_color</strong> - simplifies blend color, no deferred update needed</li>
</ol>
<p>Fixes the NIR validation failure with scalar fragment outputs. And as a nice side effect, removing the shader-based swap means fewer shader variants, fewer instructions and less overhead. <a href="https://github.com/glmark2/glmark2">glmark2</a>-es2-wayland improves from ~835 to ~874 FPS - a 4.7% performance increase.</p>
<p>Sometimes matching what the hardware vendor does is the right answer. The blob driver figured this out years ago. We just needed to look at the traces.</p>
<h2 id="thats-where-i-thought-the-story-ended">That&rsquo;s where I thought the story ended</h2>
<p>The texture-format trick has a hidden assumption baked into it: that the GPU both writes <em>and</em> reads every resource. The PE writes BGRA, the sampler is told the format is A8R8G8B8, and the byte order cancels out. It&rsquo;s a closed loop, and as long as the data never leaves the GPU, nobody outside ever sees the BGRA bytes.</p>
<p><a href="https://docs.kernel.org/driver-api/dma-buf.html">dmabuf</a> breaks the loop.</p>
<p>When a buffer is shared with another process - a Wayland compositor, a video decoder, a camera - the byte order is no longer our private business. It&rsquo;s mandated by the <a href="https://docs.kernel.org/userspace-api/dma-buf-alloc-exchange.html">DRM FourCC</a>. An external producer writes honest RGBA bytes into the buffer. Then our sampler, still convinced the format is A8R8G8B8, reads them as BGRA. Red and blue swap. And on the way out, a transfer blit happily swaps data that was already correct. The optimization that made GPU-internal rendering clean made buffer sharing wrong.</p>
<pre tabindex="0"><code>  GPU-internal (closed loop):       dmabuf (loop broken):

  PE writes BGRA                    external producer writes RGBA
       |                                  |
  sampler reads as A8R8G8B8         sampler reads as A8R8G8B8
       |                                  |
  cancels out -&gt; correct            reads RGBA as BGRA -&gt; swapped
</code></pre><h2 id="step-back-out-for-shared-resources">Step back out for shared resources</h2>
<p>The first fix is the obvious one: when a resource is shared, don&rsquo;t play the trick. Use the native A8B8G8R8 texture format so the sampler reads RGBA bytes as RGBA, skip the R/B swizzle in the BLT and RS transfer blits, and re-enable the texture shadow shortcut that the swizzle had forced us to disable. Internal resources keep the BGRA-internal optimization untouched.</p>
<p>That handles imports. But there&rsquo;s a case it doesn&rsquo;t cover: a resource <em>we</em> rendered into and then export. The PE wrote BGRA, because that&rsquo;s all the PE knows how to do. The external consumer expects native order.</p>
<p>Here a second kind of shadow shows up. Just as the sampler gets a <em>texture shadow</em> when it can&rsquo;t read the base layout, the PE gets a <em>render shadow</em> - a render-compatible copy - when it can&rsquo;t draw into the base layout. (On some GPUs, like GC2000, no single tiling satisfies both the texture engine and the pixel engine, so a resource can end up carrying both shadows.) When an exported resource is flushed, that render shadow is resolved back to the base. So we hook <code>etna_flush_resource()</code> and do the R/B swap during that copy - using the BLT destination swizzle or the RS <code>SWAP_RB</code> bit. The swap rides along on a copy we were doing anyway.</p>
<h2 id="one-buffer-two-byte-orders">One buffer, two byte orders</h2>
<p>Now the same shared buffer can be in one of two states. Just imported, or just flushed for export? Native RGBA. Freshly rendered by the PE, not yet flushed? PE-internal BGRA. A static texture format chosen at sampler-view creation can&rsquo;t be right for both.</p>
<p>So the format choice becomes dynamic. A <code>shared_native_order</code> flag tracks which order the bytes are currently in, and the sampler-view format follows from it:</p>
<table>
  <thead>
      <tr>
          <th><code>shared_native_order</code></th>
          <th>How you get there</th>
          <th>Bytes in buffer</th>
          <th>Sampler format</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>true</code></td>
          <td>set on import, and again after <code>flush_resource()</code> swaps on export</td>
          <td>native RGBA</td>
          <td><code>A8B8G8R8</code> (native)</td>
      </tr>
      <tr>
          <td><code>false</code></td>
          <td>cleared when the PE renders straight into the buffer with no render shadow, and no shader swap fixed up the bytes (see below)</td>
          <td>PE-internal BGRA</td>
          <td><code>A8R8G8B8</code> (the trick)</td>
      </tr>
  </tbody>
</table>
<p>Both texture paths - state-based and descriptor-based - pre-compute the native format variant at sampler-view creation, so picking the right one at emit time costs a single branch, not a per-frame format recompute.</p>
<h2 id="the-shader-swap-comes-back">The shader swap comes back</h2>
<p>Which brings us to LINEAR_PE GPUs, and a twist I didn&rsquo;t see coming.</p>
<p>On these GPUs, a linear shared resource is render-compatible. There is no render shadow - the PE writes straight into the buffer that gets handed to the compositor. So after a draw, the buffer holds BGRA, and <code>flush_resource()</code> would have to issue a full-surface blit to swap it. That&rsquo;s real bandwidth, on every frame, that the old shadow-based path never paid.</p>
<p>There&rsquo;s a cheaper place to do the swap: in the shader, on the way out. Which is exactly the thing this whole series set out to delete.</p>
<p>So it comes back - but only for this one case, and done properly. A per-RT <code>frag_rb_swap</code> bitmask in the shader key drives a NIR lowering pass that swaps channels 0 and 2 on the fragment output. The original shader swap fell over on scalar outputs, because there was no <code>.z</code> to swizzle from. This one widens the output variable to vec4 first, padding the missing components with undef, then applies the swizzle with an adjusted writemask:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl">   <span class="cm">/* Pad source to 4 components (undef for missing) */</span>
</span></span><span class="line"><span class="cl">   <span class="n">nir_def</span> <span class="o">*</span><span class="n">padded</span> <span class="o">=</span> <span class="nf">nir_pad_vec4</span><span class="p">(</span><span class="o">&amp;</span><span class="n">b</span><span class="p">,</span> <span class="n">src</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="cm">/* Swap R and B channels */</span>
</span></span><span class="line"><span class="cl">   <span class="kt">unsigned</span> <span class="n">swiz</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">};</span>
</span></span></code></pre></div><p>That&rsquo;s the scalar <code>rgb8_lowp_float</code> crash from the top of this post - fixed, in the one path that now needs a shader swap at all.</p>
<p>Wiring it up is a check in <code>etna_draw_vbo()</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl">   <span class="k">if</span> <span class="p">(</span><span class="nf">VIV_FEATURE</span><span class="p">(</span><span class="n">screen</span><span class="p">,</span> <span class="n">ETNA_FEATURE_LINEAR_PE</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">pfb</span><span class="o">-&gt;</span><span class="n">nr_cbufs</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">         <span class="k">struct</span> <span class="n">etna_resource</span> <span class="o">*</span><span class="n">rsc</span> <span class="o">=</span> <span class="nf">etna_resource</span><span class="p">(</span><span class="n">pfb</span><span class="o">-&gt;</span><span class="n">cbufs</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">texture</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">         <span class="k">if</span> <span class="p">(</span><span class="n">rsc</span><span class="o">-&gt;</span><span class="n">shared</span> <span class="o">&amp;&amp;</span> <span class="n">rsc</span><span class="o">-&gt;</span><span class="n">layout</span> <span class="o">==</span> <span class="n">ETNA_LAYOUT_LINEAR</span> <span class="o">&amp;&amp;</span>
</span></span><span class="line"><span class="cl">             <span class="nf">translate_pe_format_rb_swap</span><span class="p">(</span><span class="n">pfb</span><span class="o">-&gt;</span><span class="n">cbufs</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">format</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">            <span class="n">key</span><span class="p">.</span><span class="n">frag_rb_swap</span> <span class="o">|=</span> <span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">i</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">   <span class="p">}</span>
</span></span></code></pre></div><p>The bitmask is per-RT, so an MRT setup with a mix of shared and private targets does the right thing for each. And because the shader produced native bytes directly, <code>shared_native_order</code> stays true and <code>flush_resource()</code> skips its blit entirely.</p>
<p>The fixes for all of this live in a follow-up series, <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40029">etnaviv: Fix dmabuf R/B byte order for PE_FORMAT_RB_SWAP formats</a>.</p>
<h2 id="so-was-removing-the-shader-swap-a-mistake">So was removing the shader swap a mistake?</h2>
<p>No - but it wasn&rsquo;t the whole answer either.</p>
<p>The shader swap was wrong as the <em>universal</em> solution. It cost a shader-key dimension, per-RT blend-color fixups, and it crashed on scalar outputs. The texture-format trick is genuinely better for the common case, where a resource lives and dies on the GPU.</p>
<p>What the dmabuf work showed is that there is no single right place to fix R/B order. There&rsquo;s a place that&rsquo;s cheapest for each path: the texture format for GPU-internal resources, a transfer-blit swap at the CPU boundary, a flush-time swap for exported render targets, and - for LINEAR_PE, where the PE writes straight into a shared buffer - the shader, after all. The trick isn&rsquo;t picking one. It&rsquo;s knowing which boundary you&rsquo;re standing on, and swapping there.</p>
]]></content:encoded>
    </item>
    <item>
      <title>PanVK Extension Sprint: Mesa 26.1</title>
      <link>https://christian-gmeiner.info/2026-04-20-panvk-extensions/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2026-04-20-panvk-extensions/</guid>
      <description>&lt;p&gt;Last week marks the Mesa 26.1 branch point, and I wanted to take a moment to look back at what happened on the PanVK front.&lt;/p&gt;
&lt;p&gt;Spoiler: it was a busy one.&lt;/p&gt;
&lt;h3 id=&#34;the-landscape&#34;&gt;The landscape&lt;/h3&gt;
&lt;p&gt;PanVK - the Vulkan driver for Arm Mali GPUs (Valhall and newer) - is a collaborative effort. &lt;a href=&#34;https://www.collabora.com/&#34;&gt;Collabora&lt;/a&gt; has been doing incredible work on the compiler backend and the foundational infrastructure. &lt;a href=&#34;https://www.arm.com/&#34;&gt;Arm&lt;/a&gt; themselves are actively contributing to the open source Mali GPU stack as well, reviewing patches and pushing driver quality forward. On the &lt;a href=&#34;https://www.igalia.com/&#34;&gt;Igalia&lt;/a&gt; side, my focus this cycle was &lt;strong&gt;Vulkan extension coverage&lt;/strong&gt;. The kind of work that doesn&amp;rsquo;t make for flashy demos but is absolutely critical for real-world application compatibility - especially for things like &lt;a href=&#34;https://github.com/doitsujin/dxvk&#34;&gt;DXVK&lt;/a&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Last week marks the Mesa 26.1 branch point, and I wanted to take a moment to look back at what happened on the PanVK front.</p>
<p>Spoiler: it was a busy one.</p>
<h3 id="the-landscape">The landscape</h3>
<p>PanVK - the Vulkan driver for Arm Mali GPUs (Valhall and newer) - is a collaborative effort. <a href="https://www.collabora.com/">Collabora</a> has been doing incredible work on the compiler backend and the foundational infrastructure. <a href="https://www.arm.com/">Arm</a> themselves are actively contributing to the open source Mali GPU stack as well, reviewing patches and pushing driver quality forward. On the <a href="https://www.igalia.com/">Igalia</a> side, my focus this cycle was <strong>Vulkan extension coverage</strong>. The kind of work that doesn&rsquo;t make for flashy demos but is absolutely critical for real-world application compatibility - especially for things like <a href="https://github.com/doitsujin/dxvk">DXVK</a>.</p>
<h3 id="why-extensions-matter">Why extensions matter</h3>
<p>A Vulkan driver without extensions is like a car without wheels - technically complete, practically useless. Applications (and translation layers like DXVK, vkd3d-proton, and Zink) probe for specific extensions and adjust their behavior accordingly. Missing even one can mean falling back to a slower path or refusing to run entirely.</p>
<p>Three different things drove the extension work this cycle:</p>
<ul>
<li><strong>The Proton stack</strong> - extensions consumed by DXVK and vkd3d-proton, the translation layers that make D3D9–12 games run on Vulkan.</li>
<li><strong>DDK feature parity</strong> - extensions Arm&rsquo;s binary Mali driver exposes that PanVK didn&rsquo;t yet, tracked in the <a href="https://gitlab.freedesktop.org/panfrost/mesa/-/work_items/125">DDK feature parity ticket</a>.</li>
<li><strong>Catching up on <a href="https://mesamatrix.net/">mesamatrix.net</a></strong> - closing the visible gap with the other Mesa Vulkan drivers (RADV, ANV, Turnip).</li>
</ul>
<p>So I set out to close gaps. Lots of them.</p>
<h3 id="the-proton-stack-essentials">The Proton stack essentials</h3>
<p>These are extensions DXVK and vkd3d-proton actually require - not just nice-to-haves on a recommendation list. Each one unblocks something concrete in the D3D-to-Vulkan translation path.</p>
<p><strong><code>VK_EXT_conditional_rendering</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40452">!40452</a>) was probably the most involved piece of work. D3D12 has predicated rendering (<code>SetPredication</code>), and vkd3d-proton uses this extension to implement it efficiently. It wasn&rsquo;t a simple &ldquo;flip a bit&rdquo; situation - I had to add the core state tracking, wrap all draw and dispatch calls with conditional checks, handle inherited state in secondary command buffers, and make sure meta operations (like internal clears and resolves) properly disable conditional rendering so they don&rsquo;t get accidentally skipped. That ended up being five patches touching draw paths, dispatch, and the secondary command buffer inheritance logic.</p>
<p><strong><code>VK_VALVE_mutable_descriptor_type</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40254">!40254</a>) is one of those extensions that exists purely because Valve needed it. In D3D, descriptor types are more fluid than in Vulkan - a descriptor slot might hold a sampler one frame and a storage buffer the next. vkd3d-proton enables this to avoid expensive descriptor set re-creation when types change. It&rsquo;s a trivial alias of the already-supported <code>VK_EXT_mutable_descriptor_type</code>, so enabling it was a one-liner.</p>
<p><strong><code>VK_EXT_memory_budget</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40246">!40246</a>) lets applications (and both DXVK and vkd3d-proton) query how much GPU memory is actually available versus how much is in use. Without it, apps are flying blind on memory management, which can lead to over-allocation and stuttering. Getting the heap budget reporting right required hooking into the kernel memory accounting.</p>
<p><strong><code>VK_EXT_attachment_feedback_loop_layout</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40498">!40498</a>) - feedback loops let you read from an attachment that you&rsquo;re simultaneously rendering to (think screen-space effects that sample the current framebuffer). DXVK uses this in its D3D9 hazard layout path to avoid artifacts in certain games.</p>
<p><strong><code>VK_EXT_shader_stencil_export</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39944">!39944</a>) - allows fragment shaders to write stencil values directly, rather than relying on the fixed-function stencil path. DXVK leans on this in its meta-copy and meta-resolve paths, and vkd3d-proton enables it too. The Panfrost stack already supported everything needed; literally a one-line advertisement in <code>physical_device.c</code>.</p>
<p><strong><code>VK_KHR_shader_untyped_pointers</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40457">!40457</a>, v9+) - a newer KHR extension that relaxes pointer type requirements in SPIR-V. DXVK calls this out as a dependency for descriptor heaps. Restricted to v9+ because Bifrost has issues with 8-bit vector loads through untyped pointers combined with 16-bit storage. Also needed to lower memcpy derefs before explicit IO lowering.</p>
<h3 id="catching-up-to-the-ddk">Catching up to the DDK</h3>
<p>The panfrost keeps a <a href="https://gitlab.freedesktop.org/panfrost/mesa/-/work_items/125">DDK feature parity ticket</a> tracking everything Arm&rsquo;s binary Mali driver exposes that PanVK doesn&rsquo;t yet. Four of those got crossed off this cycle:</p>
<ul>
<li><strong><code>VK_ARM_scheduling_controls</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40063">!40063</a>, CSF only) - an ARM-specific extension for controlling shader core scheduling on Command Stream Frontend (CSF) hardware. I also fixed the per-queue shader core count so CSF group creation uses the right values.</li>
<li><strong><code>VK_EXT_legacy_dithering</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39781">!39781</a>) - implements ordered dithering in the blending stage, which some applications expect from legacy APIs. Wired up the existing Panfrost dithering infrastructure (<code>pan_dithered_format_from_pipe_format()</code>) — just plumbing the <code>VK_RENDERING_ENABLE_LEGACY_DITHERING_BIT_EXT</code> flag through the blend descriptor and color attachment internal conversion paths.</li>
<li><strong><code>VK_EXT_rgba10x6_formats</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40653">!40653</a>) - a last-minute addition that just squeezed in before the branch point. This required adding the <code>PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM</code> format to Mesa&rsquo;s gallium format table first, then wiring it up in PanVK. Used for 10-bit per channel content in video and HDR scenarios.</li>
<li><strong><code>VK_EXT_astc_decode_mode</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39799">!39799</a>) - controls the format used when decoding ASTC compressed textures, allowing apps to choose lower-precision decoding for performance. The Panfrost hardware already supports controlling ASTC decode precision via the Decode Wide plane descriptor field; just needed to parse <code>VkImageViewASTCDecodeModeEXT</code> from the image view pNext chain and set <code>astc.narrow</code> accordingly. v9+ only because the relevant ASTC plane descriptor fields only exist from Valhall onward.</li>
</ul>
<h3 id="catching-up-on-mesamatrix">Catching up on mesamatrix</h3>
<p><a href="https://mesamatrix.net/">mesamatrix.net</a> tracks Vulkan extension support across the Mesa drivers. The remaining extensions this cycle were about closing the visible gap with RADV, ANV, and Turnip — extensions that don&rsquo;t have a single big consumer driving them, but whose absence shows up as red squares on the matrix and as silent fallbacks in apps that probe for them.</p>
<ul>
<li><strong><code>VK_EXT_color_write_enable</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39913">!39913</a>) - per-attachment control over which color channels actually get written. The common Vulkan runtime already handled all the pipeline state and dynamic command plumbing, and panvk&rsquo;s blend descriptor emission was already consuming <code>color_write_enables</code>, so this was effectively an &ldquo;advertise the feature&rdquo; change.</li>
<li><strong><code>VK_EXT_depth_clamp_control</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39925">!39925</a>) - lets applications specify a custom depth clamp range instead of always clamping to the viewport&rsquo;s minDepth/maxDepth. Mali GPUs have native <code>LOW_DEPTH_CLAMP</code>/<code>HIGH_DEPTH_CLAMP</code> registers, so it was a matter of wiring the existing runtime state through to those.</li>
<li><strong><code>VK_EXT_attachment_feedback_loop_dynamic_state</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40498">!40498</a>) - the dynamic-state companion to <code>VK_EXT_attachment_feedback_loop_layout</code> above; lets you toggle feedback-loop state per draw call without pipeline rebuilds.</li>
<li><strong><code>VK_EXT_map_memory_placed</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40315">!40315</a>) - lets applications control <em>where</em> in their virtual address space GPU memory gets mapped. This simplified <code>pan_kmod_bo_mmap()</code> to always map the whole BO, cleaning up the kernel module interface.</li>
<li><strong><code>VK_EXT_shader_atomic_float</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40506">!40506</a>) - atomic operations on float values in shaders. The existing <code>axchg</code> instruction is type-agnostic, so no compiler changes were needed; image atomics are already lowered to global atomics. Just had to add <code>R32_FLOAT</code> to the storage-image-atomic format flag.</li>
<li><strong><code>VK_EXT_nested_command_buffer</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40120">!40120</a>, v10+) - allows secondary command buffers to call other secondary command buffers. The CSF backend&rsquo;s <code>cs_call()</code> is a hardware call/return instruction that nests naturally, and the existing <code>CmdExecuteCommands</code> already does the caller/callee state merging. The 8-level hardware call stack, minus one for the kernel ringbuffer call and two reserved for future driver use, leaves <code>maxCommandBufferNestingLevel</code> at 5.</li>
<li><strong><code>VK_EXT_image_view_min_lod</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39938">!39938</a>) - allows clamping the minimum LOD at the image view level rather than just the sampler. Mali v6+ has per-texture-descriptor LOD clamp fields independent from the sampler&rsquo;s, so this just plumbs <code>vk_image_view::min_lod</code> through <code>pan_image_view</code> into the texture descriptor — no shader lowering or descriptor merging needed.</li>
<li><strong><code>VK_EXT_zero_initialize_device_memory</code></strong> (<a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39658">!39658</a>) - guarantees that newly allocated device memory is zeroed. The kernel side already does the heavy lifting — <code>panfrost</code>/<code>panthor</code> use <code>drm_gem_shmem</code>, which serves zeroed pages from the shmem subsystem. And since panvk treats layout transitions as no-ops, <code>VK_IMAGE_LAYOUT_ZERO_INITIALIZED_EXT</code> falls out for free. (Did need one format-table fix: dropping <code>STORAGE_IMAGE</code> support from compressed formats to avoid crashes in the new dEQP tests.)</li>
</ul>
<h3 id="by-the-numbers">By the numbers</h3>
<p>That&rsquo;s <strong>18 extensions</strong> across roughly a dozen merge requests - ranging from single-patch additions to multi-patch series like conditional rendering. Collectively they represent a meaningful shift in what PanVK can claim to support: more of the Proton stack working out of the box, four more checkboxes against the DDK, and fewer red squares on the mesamatrix.</p>
<h3 id="whats-next">What&rsquo;s next</h3>
<p>The extension sprint isn&rsquo;t over - there are still gaps to fill, and each one removed makes PanVK more viable for real workloads. But 26.1 was a good milestone. The driver is getting to the point where you can throw a DXVK game at it and have a reasonable expectation that it just works.</p>
<p>Back to it. ⚡</p>
]]></content:encoded>
    </item>
    <item>
      <title>GLES3 on etnaviv: Fixing the Hard Parts</title>
      <link>https://christian-gmeiner.info/2026-02-20-gles3-on-etnaviv-fixing-the-hard-parts/</link>
      <pubDate>Fri, 20 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2026-02-20-gles3-on-etnaviv-fixing-the-hard-parts/</guid>
      <description>&lt;p&gt;This is the start of a series about getting OpenGL ES 3.0 conformance on Vivante GC7000 hardware using the open-source etnaviv driver in Mesa. Thanks to &lt;a href=&#34;https://www.igalia.com/&#34;&gt;Igalia&lt;/a&gt; for giving me the opportunity to spend some time on these topics.&lt;/p&gt;
&lt;h2 id=&#34;where-we-are&#34;&gt;Where We Are&lt;/h2&gt;
&lt;p&gt;etnaviv has supported GLES2 on Vivante GPUs for a long time. GLES3 support has been progressing steadily, but the remaining dEQP failures are the stubborn ones - the cases where the hardware doesn&amp;rsquo;t quite do what the spec says, and the driver has to get creative.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>This is the start of a series about getting OpenGL ES 3.0 conformance on Vivante GC7000 hardware using the open-source etnaviv driver in Mesa. Thanks to <a href="https://www.igalia.com/">Igalia</a> for giving me the opportunity to spend some time on these topics.</p>
<h2 id="where-we-are">Where We Are</h2>
<p>etnaviv has supported GLES2 on Vivante GPUs for a long time. GLES3 support has been progressing steadily, but the remaining dEQP failures are the stubborn ones - the cases where the hardware doesn&rsquo;t quite do what the spec says, and the driver has to get creative.</p>
<p>These aren&rsquo;t missing feature bits or unimplemented extensions. These are the problems where you stare at a command stream trace from the proprietary blob driver and realize they&rsquo;re doing something <em>completely different</em> from what you&rsquo;d expect, because the hardware has a quirk that nobody documented.</p>
<h2 id="the-approach">The Approach</h2>
<p>My workflow for each fix follows a pattern:</p>
<ol>
<li><strong>Run the failing dEQP test</strong>, note the failure mode (wrong pixels, crash, GPU hang)</li>
<li><strong>Capture command stream traces</strong> from both the blob (proprietary driver) and etnaviv for the same test</li>
<li><strong>Compare the traces</strong> - what states differ? What draw calls differ? Is the blob doing extra work?</li>
<li><strong>Understand why</strong> - read the spec, reason about the hardware behavior, figure out what the blob knows that we don&rsquo;t</li>
<li><strong>Implement the fix</strong> in Mesa, test, iterate</li>
</ol>
<p>The blob traces are invaluable. Vivante&rsquo;s proprietary driver has years of hardware workarounds baked in. When something doesn&rsquo;t work, the answer is usually hiding in the trace.</p>
<h2 id="the-hardware">The Hardware</h2>
<p>The primary test target is a GC7000 rev 6214 (HALTI5 generation). This is a capable GPU found in the NXP i.MX8MQ SoC. It has a BLT engine, texture descriptors, and most of the features needed for GLES3 - but also its own set of rasterization quirks and interpolation behaviors that need workarounds.</p>
<p>In the future, I plan to expand the focus to the broader GC7000 GPU family.</p>
<h2 id="up-next">Up Next</h2>
<p>The first post will tackle the R/B swap problem - the PE always writes pixels in BGRA byte order, and we&rsquo;ve been fixing it in the shader. The blob has a simpler answer. Stay tuned.</p>
<h2 id="following-along">Following Along</h2>
<p>All of this work happens upstream in <a href="https://gitlab.freedesktop.org/mesa/mesa">Mesa</a>.</p>
<p>If you&rsquo;re interested in GPU driver development, these posts aim to show what the work actually looks like &ndash; not just the final patch, but the debugging, the trace analysis, and the reasoning that gets you there.</p>
]]></content:encoded>
    </item>
    <item>
      <title>My first Vulkan extension</title>
      <link>https://christian-gmeiner.info/2026-02-13-my-first-vulkan-extension/</link>
      <pubDate>Fri, 13 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2026-02-13-my-first-vulkan-extension/</guid>
      <description>&lt;p&gt;After years of working on etnaviv - a Gallium/OpenGL driver for Vivante GPUs - I&amp;rsquo;ve been wanting to get into Vulkan. As part of my work at &lt;a href=&#34;https://www.igalia.com/&#34;&gt;Igalia&lt;/a&gt;, the goal was to bring &lt;a href=&#34;https://docs.vulkan.org/refpages/latest/refpages/source/VK_EXT_blend_operation_advanced.html&#34;&gt;&lt;code&gt;VK_EXT_blend_operation_advanced&lt;/code&gt;&lt;/a&gt; to lavapipe. But rather than going straight there, I started with Honeykrisp - the Vulkan driver for Apple Silicon - as a first target: a real hardware driver to validate the implementation against before wiring it up in a software renderer. My first Vulkan extension, and my first real contribution to Honeykrisp.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>After years of working on etnaviv - a Gallium/OpenGL driver for Vivante GPUs - I&rsquo;ve been wanting to get into Vulkan. As part of my work at <a href="https://www.igalia.com/">Igalia</a>, the goal was to bring <a href="https://docs.vulkan.org/refpages/latest/refpages/source/VK_EXT_blend_operation_advanced.html"><code>VK_EXT_blend_operation_advanced</code></a> to lavapipe. But rather than going straight there, I started with Honeykrisp - the Vulkan driver for Apple Silicon - as a first target: a real hardware driver to validate the implementation against before wiring it up in a software renderer. My first Vulkan extension, and my first real contribution to Honeykrisp.</p>
<h1 id="why-this-extension">Why this extension?</h1>
<p>A customer needed advanced blending support in lavapipe, so the extension choice was made for me. But it turned out to be a great fit for a first extension - useful, self-contained, and not a multi-month rabbit hole. Standard Vulkan blending is limited to basic operations like add and subtract with blend factors. That&rsquo;s fine for most rendering, but if you want Photoshop-style effects - multiply, screen, overlay, color dodge, color burn - you&rsquo;re stuck doing it manually in shaders or with extra render passes.</p>
<p>The extension adds 19 blend operations that handle all of this in the fixed-function pipeline. Useful for UI toolkits, image editors, and anywhere you need creative compositing.</p>
<h1 id="the-journey">The journey</h1>
<p>What started as &ldquo;just wire up an extension&rdquo; turned into a proper refactoring adventure. The existing blend infrastructure in Mesa was scattered - OpenGL had its own enum definitions, Vulkan had separate conversions, and the actual NIR blend math lived in glsl-specific code.</p>
<p>So I took a step back and cleaned things up. Moved the blend mode enums into a shared util/blend.h header. Added proper helpers in the Vulkan runtime for converting between API types. Then came the fun part: implementing the actual blend equations in nir/lower_blend.</p>
<p>Each of those 19 blend modes has its own formula from the spec. Some are simple (multiply is just src * dst), others get hairy with conditionals and special cases for luminosity and saturation. About 570 lines of NIR code later, I had a lowering pass that any Mesa driver can use.</p>
<p>For example, here&rsquo;s how the <a href="https://docs.vulkan.org/spec/latest/chapters/framebuffer.html#framebuffer-blend-advanced">spec defines advanced blending</a>. Each mode plugs into a general equation:</p>
<pre tabindex="0"><code>RGB = f(Cs,Cd) * X * p0 + Cs * Y * p1 + Cd * Z * p2
A   =            X * p0 +      Y * p1 +      Z * p2
</code></pre><p>Where <code>p0</code>, <code>p1</code>, <code>p2</code> are weighting factors based on source/destination alpha coverage, and <code>f(Cs,Cd)</code> is the per-mode blend function. For overlay - probably the most recognizable blend mode from Photoshop - the spec defines:</p>
<pre tabindex="0"><code>f(Cs,Cd) = 2*Cs*Cd,              if Cd &lt;= 0.5
           1 - 2*(1-Cs)*(1-Cd),  otherwise
</code></pre><p>And here&rsquo;s that same formula expressed as NIR - Mesa&rsquo;s intermediate representation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">static</span> <span class="kr">inline</span> <span class="n">nir_def</span> <span class="o">*</span>
</span></span><span class="line"><span class="cl"><span class="nf">blend_overlay</span><span class="p">(</span><span class="n">nir_builder</span> <span class="o">*</span><span class="n">b</span><span class="p">,</span> <span class="n">nir_def</span> <span class="o">*</span><span class="n">src</span><span class="p">,</span> <span class="n">nir_def</span> <span class="o">*</span><span class="n">dst</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">   <span class="cm">/* f(Cs,Cd) = 2*Cs*Cd, if Cd &lt;= 0.5
</span></span></span><span class="line"><span class="cl"><span class="cm">    *            1-2*(1-Cs)*(1-Cd), otherwise
</span></span></span><span class="line"><span class="cl"><span class="cm">    */</span>
</span></span><span class="line"><span class="cl">   <span class="n">nir_def</span> <span class="o">*</span><span class="n">rule_1</span> <span class="o">=</span> <span class="nf">nir_fmul</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="nf">nir_fmul</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">src</span><span class="p">,</span> <span class="n">dst</span><span class="p">),</span> <span class="nf">imm3</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="mf">2.0</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">   <span class="n">nir_def</span> <span class="o">*</span><span class="n">rule_2</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">      <span class="nf">nir_fsub</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="nf">imm3</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">               <span class="nf">nir_fmul</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="nf">nir_fmul</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="nf">nir_fsub</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="nf">imm3</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">),</span> <span class="n">src</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">                                        <span class="nf">nir_fsub</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="nf">imm3</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">),</span> <span class="n">dst</span><span class="p">)),</span>
</span></span><span class="line"><span class="cl">                         <span class="nf">imm3</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="mf">2.0</span><span class="p">)));</span>
</span></span><span class="line"><span class="cl">   <span class="k">return</span> <span class="nf">nir_bcsel</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="nf">nir_fge</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="nf">imm3</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="mf">0.5f</span><span class="p">),</span> <span class="n">dst</span><span class="p">),</span> <span class="n">rule_1</span><span class="p">,</span> <span class="n">rule_2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p><code>nir_fmul</code>, <code>nir_fsub</code>, <code>nir_bcsel</code> - multiply, subtract, conditional select. Each call builds a node in the shader&rsquo;s IR graph. This is what &ldquo;lowering&rdquo; looks like: translating a high-level blend mode into operations the GPU&rsquo;s shader core can execute. The outer framework - the <code>p0</code>/<code>p1</code>/<code>p2</code> weighting - is handled by the caller; each blend function just implements its <code>f(Cs,Cd)</code>.</p>
<h1 id="the-turnip-surprise">The Turnip surprise</h1>
<p>Everything was working on Honeykrisp, tests were passing, life was good. Then the merge pipeline started failing - on Turnip (the Adreno Vulkan driver). Not my code, not my hardware, but my changes were breaking it.</p>
<p>I reached out for help, and Zan Dobersek stepped up. After some digging, he found the culprit: I was violating a subtle corner of the spec around attachmentCount. Turns out, when certain dynamic states are set and advancedBlendCoherentOperations isn&rsquo;t enabled, attachmentCount gets ignored entirely. My state tracking code wasn&rsquo;t accounting for that.</p>
<p>One fixup commit later, Turnip was happy again. This is the part they don&rsquo;t tell you about Vulkan extensions - you&rsquo;re not just implementing for your driver, you&rsquo;re touching shared infrastructure that every driver depends on. And the Mesa CI will absolutely let you know if you break something.</p>
<h1 id="lavapipe-landed">lavapipe landed</h1>
<p>One week later, lavapipe has it too. This was the original goal, and the shared infrastructure did exactly what it was supposed to - the <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39612">lavapipe MR</a> is mostly just flipping the extension on. The lowering pass, the enum plumbing, the runtime helpers - all reused as-is. The full <code>dEQP-VK.pipeline.*.blend_operation_advanced.*</code> test suite passes on both drivers.</p>
<p>Two drivers in two weeks. That&rsquo;s what building the right abstractions gets you.</p>
<h1 id="whats-next">What&rsquo;s next</h1>
<p>The shared NIR lowering pass is there for any Mesa Vulkan driver to use. If your hardware doesn&rsquo;t have native advanced blending support, enabling the extension is now mostly plumbing. I&rsquo;m curious to see if other drivers pick it up.</p>
<p>For me, this was a good first step into Vulkan - and into working on Honeykrisp. I&rsquo;m looking forward to what comes next.</p>
<p>The <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38929">Honeykrisp/NIR MR</a> and the <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39612">lavapipe MR</a> are both merged if you want to look at the code. Thanks to Alyssa Rosenzweig for the review and guidance, and to Zan Dobersek for debugging the Turnip regression with me.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Multiple Render Targets for etnaviv</title>
      <link>https://christian-gmeiner.info/2025-01-16-mrt/</link>
      <pubDate>Thu, 16 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2025-01-16-mrt/</guid>
      <description>&lt;p&gt;Modern graphics programming revolves around achieving high-performance rendering and visually stunning effects. Among OpenGL’s capabilities, Multiple Render Targets (MRTs) are particularly valuable for enabling advanced rendering techniques with greater efficiency.&lt;/p&gt;
&lt;p&gt;With the latest release of &lt;a href=&#34;https://docs.mesa3d.org/relnotes/24.3.0.html&#34;&gt;Mesa 24.03&lt;/a&gt; and the commitment from &lt;a href=&#34;https://www.igalia.com/&#34;&gt;Igalia&lt;/a&gt;, the etnaviv GPU driver now includes support for MRTs. If you’ve ever wondered how MRTs can transform your graphics pipeline or are curious about the challenges of implementing this feature, this blog post is for you.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Modern graphics programming revolves around achieving high-performance rendering and visually stunning effects. Among OpenGL’s capabilities, Multiple Render Targets (MRTs) are particularly valuable for enabling advanced rendering techniques with greater efficiency.</p>
<p>With the latest release of <a href="https://docs.mesa3d.org/relnotes/24.3.0.html">Mesa 24.03</a> and the commitment from <a href="https://www.igalia.com/">Igalia</a>, the etnaviv GPU driver now includes support for MRTs. If you’ve ever wondered how MRTs can transform your graphics pipeline or are curious about the challenges of implementing this feature, this blog post is for you.</p>
<h1 id="understanding-multiple-render-targets-mrts">Understanding Multiple Render Targets (MRTs)</h1>
<p>At its core, MRTs allow rendering to multiple images or &ldquo;render targets&rdquo; simultaneously during a single rendering pass. These render targets are buffers or textures that store various scene data such as color, depth, or normals. By writing to multiple targets at once, MRTs enable developers to:</p>
<ul>
<li>Enhance efficiency by reducing the number of rendering passes.</li>
<li>Implement sophisticated rendering techniques, such as deferred shading, which decouples geometry processing from lighting and shading.</li>
</ul>
<p>Here’s a simple OpenGLES shader example demonstrating how to use MRTs:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="c1">// Vertex Shader
</span></span></span><span class="line"><span class="cl"><span class="nf">layout</span><span class="p">(</span><span class="n">location</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="n">in</span> <span class="n">vec2</span> <span class="n">inPosition</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">gl_Position</span> <span class="o">=</span> <span class="nf">vec4</span><span class="p">(</span><span class="n">inPosition</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Fragment Shader
</span></span></span><span class="line"><span class="cl"><span class="nf">layout</span><span class="p">(</span><span class="n">location</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="n">out</span> <span class="n">vec4</span> <span class="n">fragColor1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="nf">layout</span><span class="p">(</span><span class="n">location</span> <span class="o">=</span> <span class="mi">1</span><span class="p">)</span> <span class="n">out</span> <span class="n">vec4</span> <span class="n">fragColor2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">fragColor1</span> <span class="o">=</span> <span class="nf">vec4</span><span class="p">(</span><span class="mf">1.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">);</span> <span class="c1">// Red
</span></span></span><span class="line"><span class="cl">    <span class="n">fragColor2</span> <span class="o">=</span> <span class="nf">vec4</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">);</span> <span class="c1">// Blue
</span></span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This code renders two render targets: one red and one blue, by declaring two output locations in the fragment shader and writing different colors to each of them.</p>
<h1 id="how-mrts-are-used">How MRTs Are Used</h1>
<p>MRTs play an important role in graphics applications. Here are some of their most common use cases:</p>
<h3 id="1-deferred-rendering">1. <strong>Deferred Rendering</strong></h3>
<p>MRTs are the backbone of deferred shading, a technique where scene geometry is rendered to multiple targets, storing data like positions, normals, and albedo. This data is then processed in a second pass to calculate lighting, enabling advanced effects like dynamic shadows and screen-space reflections.</p>
<h3 id="2-post-processing-effects">2. <strong>Post-Processing Effects</strong></h3>
<p>By writing intermediate results to multiple targets, MRTs facilitate a wide range of effects, including bloom, depth of field, and ambient occlusion.</p>
<h3 id="3-debugging-and-visualization">3. <strong>Debugging and Visualization</strong></h3>
<p>Developers can output different types of scene data simultaneously for debugging or creating visualizations.</p>
<h1 id="implementing-mrts-in-etnaviv">Implementing MRTs in etnaviv</h1>
<p>Adding MRT support to the etnaviv driver involved significant reverse engineering and experimentation. Here’s a look at some of the challenges and solutions:</p>
<h2 id="reverse-engineering-the-gpu">Reverse Engineering the GPU</h2>
<p>The reverse engineering process begins with examining the limits exposed by the binary blob driver, such as the value returned by <code>GL_MAX_DRAW_BUFFERS</code>. Different Vivante GPU generations (HALTI) support varying numbers of render targets, requiring repeated testing and analysis.</p>
<h3 id="lay-the-foundation">Lay the foundation</h3>
<p>I started with Freedreno’s <a href="https://gitlab.freedesktop.org/freedreno/freedreno/-/blob/master/tests-3d/test-mrt-fbo.c?ref_type=heads">test-mrt-fbo</a> to get a rought idea of what needed to be done. Hours later, I identified most of the necessary bits and GPU states I had seen in the command stream dumps generated by the proprietary driver.</p>
<p>The first goal was to get a very basic piglit MRT test working on the GC7000 (HALTI5) GPU, rendering correctly with etnaviv. In this phase of reverse engineering, I usually hack around in the driver and my git commit history is full of &lsquo;hack/wip&rsquo; commits. This helps me keep track of the (breaking) changes I make during the process.</p>
<p>Looking at the changes I had made until here, it was clear that I had touched nearly every part of the gallium driver. It started with compiler changes to handle the extra color outputs and ended with the extra MRT states that needed to be emitted. And, to be honest, at this stage I also had broken some other CTS and piglit tests, but that was something to be taken care of later.</p>
<p>When I tried some more complex piglit tests that used sparse render targets, I saw that they failed and realized, after reverse-engineering the proprietary driver some more, that I needed to work on remapping some information provided by NIR in Mesa about fragment shader outputs into compressed info the driver needed. That didn&rsquo;t make all relevant Piglit tests pass, but I was getting close.</p>
<h3 id="will-it-work-on-another-gpu">Will it work on another GPU?</h3>
<p>The branch was then tested on older Vivante GPUs, like the GC3000 (HALTI2). None of the tests passed initially, as state emissions differed and the maximum MRT count was lower (4 vs. 8). Updating the state emission logic addressed these issues.</p>
<h3 id="whats-wrong-with-the-tile-status">Whats wrong with the Tile Status?</h3>
<p>As I always want to provide the best experience for all etnaviv users, I wanted to support this shiny new feature even on a much older Vivante GPU generation - GC2000 (HALT0) found in i.MX6 boards.</p>
<p>My hopes where high that my git branch would just work but, as usual, I was wrong. The traces from the vendor driver showed something interesting. There was no tile status (TS) usage found in the traces and I could confirm piglit was happy when I used <code>ETNA_MESA_DEBUG=no_ts</code>.</p>
<p>You might wonder that the ominous <code>Tile Status</code> might be. Let me give you a quick summary.</p>
<p>A render target is divided in tiles, and every tile has a couple of status flags. An auxiliary buffer - the so called <code>Tile Status</code> buffer - associated with each render surface keeps track of these tile status flags. One of these flags is the clear flag, that signifies that the tile has been cleared. For example, a fast clear happens by setting the clear bit for each tile instead of clearing the actual surface data.</p>
<p>I found a way to fix this problem too and then moved to CI.</p>
<h2 id="ci-to-test-them-all">CI to test them all</h2>
<p>If you&rsquo;ve followed me until here, you know that I worked on one HALTI and moved to another and never tested if I had broken any of the other HALTI&rsquo;s. It was time to let etnaviv&rsquo;s CI do its work and, as expected, I discovered I had broken HALTI5. After a local debugging session I got it into a working state. While I was very close to being ready to submit an MR and incorporate review feedback, there was one last thing I need to take care of&hellip;</p>
<h2 id="halti5-enhancements-for-mrts">HALTI5+ Enhancements for MRTs</h2>
<p>It turns out that a HALTI5 GPU can support more OpenGL extensions as it has even more GPU states that fall under the MRT umbrella. The MRT ground work that was already in place allowed me to implement the following ones:</p>
<h3 id="1-gl_">1. <strong>GL_EXT_draw_buffers2</strong></h3>
<p>This extension allows independent blending and write masking for each render target in an MRT setup. Developers can specify unique blending equations and masks for each target, offering unparalleled control over how data is combined.</p>
<h3 id="2-gl_">2. <strong>GL_ARB_draw_buffers_blend</strong></h3>
<p>This feature extends blending capabilities even further, enabling per-buffer blending equations and functions. It’s especially useful for advanced rendering pipelines, such as deferred shading and post-processing, where different render targets may require entirely distinct blending behaviors.</p>
<h1 id="conclusion">Conclusion</h1>
<p>With the addition of <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26565">MRT support</a> and the powerful HALTI5+ enhancements like <code>GL_EXT_draw_buffers2</code> and <code>GL_ARB_draw_buffers_blend</code>, the etnaviv driver has reached a significant milestone.</p>
<p>MRT support is also a key feature for achieving full GLES3 compliance, marking a step forward in modernizing the capabilities of the etnaviv driver.</p>
<p>For detailed reverse engineering results, check out this <a href="https://github.com/etnaviv/etna_vi">repository</a>, which uses the rnndb format to describe GPU states and bits. The MRT specific changes can be found in this <a href="https://github.com/etnaviv/etna_viv/commit/ce1ddcd09b7e15a8893722214bb668f890fcf486">commit</a>.</p>
<p><strong>What’s next?</strong> Stay tuned for more updates on the etnaviv driver as we continue to push more features upstream.</p>
]]></content:encoded>
    </item>
    <item>
      <title>CI-Tron: A Long Road to a Better Board Farm</title>
      <link>https://christian-gmeiner.info/2024-10-30-ci-tron-a-long-road-to-a-better-board-farm/</link>
      <pubDate>Wed, 30 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2024-10-30-ci-tron-a-long-road-to-a-better-board-farm/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m a big supporter of finding problems before they get into the code base. The earlier you catch issues, the easier they are to fix. One of the main tools that helps with this is a Continuous Integration (CI) farm. A CI farm allows you to run extensive tests like &lt;a href=&#34;https://github.com/KhronosGroup/VK-GL-CTS&#34;&gt;deqp&lt;/a&gt; or &lt;a href=&#34;https://piglit.freedesktop.org&#34;&gt;piglit&lt;/a&gt; on a merge request or even on a private git branch before any code is merged, which significantly helps catch problems early.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I&rsquo;m a big supporter of finding problems before they get into the code base. The earlier you catch issues, the easier they are to fix. One of the main tools that helps with this is a Continuous Integration (CI) farm. A CI farm allows you to run extensive tests like <a href="https://github.com/KhronosGroup/VK-GL-CTS">deqp</a> or <a href="https://piglit.freedesktop.org">piglit</a> on a merge request or even on a private git branch before any code is merged, which significantly helps catch problems early.</p>
<p>I&rsquo;m not the first one at <a href="https://www.igalia.com">Igalia</a> to think this is really important. We already have a large Raspberry Pi board farm available on freedesktop&rsquo;s GitLab instance that serves as a powerful tool for validating changes before they hit the main branch.</p>
<p>For a while, however, the etnaviv board farm has been offline. The main reason? I needed to clean up the setup: re-house it in a proper rack, redo all the wiring, and add more devices. What initially seemed like a few days&rsquo; worth of work spiraled into months of delay, mostly because I wanted to transition to using <a href="https://gitlab.freedesktop.org/gfx-ci/ci-tron">ci-tron</a>.</p>
<h1 id="getting-familiar-with-the-ci-tron-setup">Getting Familiar with the Ci-Tron Setup</h1>
<p>Before diving into my journey, let’s quickly cover what makes up a ci-tron board farm.</p>
<ul>
<li><strong>Ci-Tron Gateway</strong>: This component is the central hub that manages devices.</li>
<li><strong>PDU (Power Delivery Unit)</strong>: A PDU is a device that manages the electrical power distribution to all the components in the CI farm. It allows you to remotely control the power, including power cycling devices, which is crucial for automating device management.</li>
<li><strong>DUT (Device Under Test)</strong>: The heart of the CI farm—these are the devices where the actual testing happens.</li>
</ul>
<h1 id="the-long-road-to-a-working-farm">The Long Road to a Working Farm</h1>
<p>Over the past few months, I’ve been slowly preparing for the big ci-tron transition. The first step was ensuring my <a href="https://www.robot-electronics.co.uk/eth008b.html">PDU</a> was compatible. It wasn&rsquo;t initially supported, but after some hacking, I got it working and submitted a <a href="https://gitlab.freedesktop.org/gfx-ci/ci-tron/-/merge_requests/715">merge request (MR)</a>. After a few rounds of revisions, it was merged, expanding ci-tron’s PDU support significantly.</p>
<p>The next and most critical step was getting a DUT to boot up correctly. Initially, ci-tron only supported iPXE as a boot method, but my devices are using U-Boot. I tried to make it work anyway, but the network initialization failed too often, and I found myself sinking hours into debugging.</p>
<p>Thankfully, rudimentary support for a <a href="https://www.u-boot.org">U-Boot</a> based boot flow was eventually added. After some tweaks, I managed to get my DUTs booting — but not without complications. A major problem was getting the correct Device Tree Blob (DTB) to load, which was needed for ci-tron&rsquo;s training rounds. A Device Tree Blob (DTB) is a binary representation of the hardware layout of a device. The DTB is used by the Linux kernel to understand the hardware configuration, including components like the CPU, memory, and peripherals. In my case, ensuring that the correct DTB was provided was crucial for the DUT to boot and be correctly managed by ci-tron. While integrating the DTB into U-Boot was suggested, it wasn’t ideal. Updating the bootloader just to change a DTB is cumbersome, especially with multiple devices in the farm.</p>
<p>With the booting issue taking up too much time, I decided to put it on hold and focus on something else: gfxinfo.</p>
<h1 id="gfxinfo-integration-challenges">Gfxinfo Integration Challenges</h1>
<p>gfxinfo is a neat feature that automatically tags a DUT based on the GPU model in the system, avoiding the need for manually assigning tags like <code>gc2000</code>. In theory, it’s very convenient—but in practice, there were hurdles.</p>
<p>gfxinfo tags Vivante GPUs using the device tree node information. However, since Vivante GPUs are quite generic, they don’t have a specific model property that uniquely identifies them. The plan was to pull this information using <code>ioctl()</code> calls to the etnaviv kernel driver. It took a lot of back and forth in review due to the internal gfxinfo API being under-documented, but after a lot of effort, I finally got the necessary code merged. You can find all of it in this <a href="https://gitlab.freedesktop.org/gfx-ci/ci-tron/-/merge_requests/758">MR</a>.</p>
<h1 id="final-push-getting-everything-to-boot">Final Push: Getting Everything to Boot</h1>
<p>There was still one major obstacle — getting the DUT to boot reliably. Luckily, <a href="https://gitlab.freedesktop.org/mupuf">mupuf</a> was already working on it and made a significant <a href="https://gitlab.freedesktop.org/gfx-ci/ci-tron/-/merge_requests/781">MR</a> with over 80 patches to address the boot issues. Introducing &ldquo;boots db,&rdquo; a feature designed to decouple the boot process, granting full control over DHCP, TFTP, and HTTP servers to each job. This is paired with YAML configurations to flexibly define the boot specifics for each board.</p>
<p>As of a few days ago, the latest official ci-tron gateway image contains everything needed to get an etnaviv DUT up and running successfully.</p>
<p><img alt="tags" loading="lazy" src="/img/ci-tron.png"></p>
<p>I have to say, I’m very impressed with the end result. It took a lot longer than I had anticipated, but we finally have a plug-and-play CI farm solution for etnaviv. There are still a few missing features—like Network Block Device (NBD) support and some advanced statistics—but the ci-tron team is doing an excellent job, and I&rsquo;m optimistic about what&rsquo;s coming next.</p>
<h1 id="conclusion-a-long-road-but-worth-it">Conclusion: A Long Road, but Worth It</h1>
<p>The journey to get the etnaviv board farm back online was longer than expected, full of unexpected challenges and technical hurdles. But it was worth it. The result is a robust, automated solution that makes CI testing easier and more reliable for everyone. With ci-tron, it’s easier to find and fix problems before they ever make it into the code base, which is exactly what a good CI setup should be all about. There is still some work to be done on the GitLab side to switch all etnaviv jobs to the new board farm.</p>
<p>If you&rsquo;re thinking about setting up your own CI farm or migrating to ci-tron, I hope my experience helps smooth the road for you a bit. It might be a long journey, but the end results are absolutely worth it.</p>
]]></content:encoded>
    </item>
    <item>
      <title>It All Started With a Nop - Part I</title>
      <link>https://christian-gmeiner.info/2024-07-11-it-all-started-with-a-nop-part1/</link>
      <pubDate>Thu, 11 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2024-07-11-it-all-started-with-a-nop-part1/</guid>
      <description>&lt;style type=&#34;text/css&#34;&gt;
     
    .notice {
        --title-color: #fff;
        --title-background-color: #6be;
        --content-color: #444;
        --content-background-color: #e7f2fa;
    }

    .notice.info {
        --title-background-color: #fb7;
        --content-background-color: #fec;
    }

    .notice.tip {
        --title-background-color: #5a5;
        --content-background-color: #efe;
    }

    .notice.warning {
        --title-background-color: #c33;
        --content-background-color: #fee;
    }

     
    @media (prefers-color-scheme:dark) {
        .notice {
            --title-color: #fff;
            --title-background-color: #069;
            --content-color: #ddd;
            --content-background-color: #023;
        }

        .notice.info {
            --title-background-color: #a50;
            --content-background-color: #420;
        }

        .notice.tip {
            --title-background-color: #363;
            --content-background-color: #121;
        }

        .notice.warning {
            --title-background-color: #800;
            --content-background-color: #400;
        }
    }

    body.dark .notice {
        --title-color: #fff;
        --title-background-color: #069;
        --content-color: #ddd;
        --content-background-color: #023;
    }

    body.dark .notice.info {
        --title-background-color: #a50;
        --content-background-color: #420;
    }

    body.dark .notice.tip {
        --title-background-color: #363;
        --content-background-color: #121;
    }

    body.dark .notice.warning {
        --title-background-color: #800;
        --content-background-color: #400;
    }

     
    .notice {
        padding: 18px;
        line-height: 24px;
        margin-bottom: 24px;
        border-radius: 4px;
        color: var(--content-color);
        background: var(--content-background-color);
    }

    .notice p:last-child {
        margin-bottom: 0
    }

     
    .notice-title {
        margin: -18px -18px 12px;
        padding: 4px 18px;
        border-radius: 4px 4px 0 0;
        font-weight: 700;
        color: var(--title-color);
        background: var(--title-background-color);
    }

     
    .icon-notice {
        display: inline-flex;
        align-self: center;
        margin-right: 8px;
    }

    .icon-notice img,
    .icon-notice svg {
        height: 1em;
        width: 1em;
        fill: currentColor;
    }

    .icon-notice img,
    .icon-notice.baseline svg {
        top: .125em;
        position: relative;
    }
&lt;/style&gt;&lt;div class=&#34;notice note&#34; &gt;
    &lt;p class=&#34;notice-title&#34;&gt;
        &lt;span class=&#34;icon-notice baseline&#34;&gt;
            &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 128 300 300&#34;&gt;
  &lt;path d=&#34;M150 128c82.813 0 150 67.188 150 150 0 82.813-67.188 150-150 150C67.187 428 0 360.812 0 278c0-82.813 67.188-150 150-150Zm25 243.555v-37.11c0-3.515-2.734-6.445-6.055-6.445h-37.5c-3.515 0-6.445 2.93-6.445 6.445v37.11c0 3.515 2.93 6.445 6.445 6.445h37.5c3.32 0 6.055-2.93 6.055-6.445Zm-.39-67.188 3.515-121.289c0-1.367-.586-2.734-1.953-3.516-1.172-.976-2.93-1.562-4.688-1.562h-42.968c-1.758 0-3.516.586-4.688 1.563-1.367.78-1.953 2.148-1.953 3.515l3.32 121.29c0 2.734 2.93 4.882 6.64 4.882h36.134c3.515 0 6.445-2.148 6.64-4.883Z&#34;/&gt;
&lt;/svg&gt;

        &lt;/span&gt;Note&lt;/p&gt;</description>
      <content:encoded><![CDATA[<style type="text/css">
     
    .notice {
        --title-color: #fff;
        --title-background-color: #6be;
        --content-color: #444;
        --content-background-color: #e7f2fa;
    }

    .notice.info {
        --title-background-color: #fb7;
        --content-background-color: #fec;
    }

    .notice.tip {
        --title-background-color: #5a5;
        --content-background-color: #efe;
    }

    .notice.warning {
        --title-background-color: #c33;
        --content-background-color: #fee;
    }

     
    @media (prefers-color-scheme:dark) {
        .notice {
            --title-color: #fff;
            --title-background-color: #069;
            --content-color: #ddd;
            --content-background-color: #023;
        }

        .notice.info {
            --title-background-color: #a50;
            --content-background-color: #420;
        }

        .notice.tip {
            --title-background-color: #363;
            --content-background-color: #121;
        }

        .notice.warning {
            --title-background-color: #800;
            --content-background-color: #400;
        }
    }

    body.dark .notice {
        --title-color: #fff;
        --title-background-color: #069;
        --content-color: #ddd;
        --content-background-color: #023;
    }

    body.dark .notice.info {
        --title-background-color: #a50;
        --content-background-color: #420;
    }

    body.dark .notice.tip {
        --title-background-color: #363;
        --content-background-color: #121;
    }

    body.dark .notice.warning {
        --title-background-color: #800;
        --content-background-color: #400;
    }

     
    .notice {
        padding: 18px;
        line-height: 24px;
        margin-bottom: 24px;
        border-radius: 4px;
        color: var(--content-color);
        background: var(--content-background-color);
    }

    .notice p:last-child {
        margin-bottom: 0
    }

     
    .notice-title {
        margin: -18px -18px 12px;
        padding: 4px 18px;
        border-radius: 4px 4px 0 0;
        font-weight: 700;
        color: var(--title-color);
        background: var(--title-background-color);
    }

     
    .icon-notice {
        display: inline-flex;
        align-self: center;
        margin-right: 8px;
    }

    .icon-notice img,
    .icon-notice svg {
        height: 1em;
        width: 1em;
        fill: currentColor;
    }

    .icon-notice img,
    .icon-notice.baseline svg {
        top: .125em;
        position: relative;
    }
</style><div class="notice note" >
    <p class="notice-title">
        <span class="icon-notice baseline">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 128 300 300">
  <path d="M150 128c82.813 0 150 67.188 150 150 0 82.813-67.188 150-150 150C67.187 428 0 360.812 0 278c0-82.813 67.188-150 150-150Zm25 243.555v-37.11c0-3.515-2.734-6.445-6.055-6.445h-37.5c-3.515 0-6.445 2.93-6.445 6.445v37.11c0 3.515 2.93 6.445 6.445 6.445h37.5c3.32 0 6.055-2.93 6.055-6.445Zm-.39-67.188 3.515-121.289c0-1.367-.586-2.734-1.953-3.516-1.172-.976-2.93-1.562-4.688-1.562h-42.968c-1.758 0-3.516.586-4.688 1.563-1.367.78-1.953 2.148-1.953 3.515l3.32 121.29c0 2.734 2.93 4.882 6.64 4.882h36.134c3.515 0 6.445-2.148 6.64-4.883Z"/>
</svg>

        </span>Note</p><p>This blog post is part <strong>1</strong> of a series of blog posts about isaspec and its usage in the etnaviv GPU stack.</p>
<p>I will add here links to the other blog posts, once they are published.</p></div>

<p>The first time I heard about isaspec, I was blown away by the possibilities it opens. I am really thankful that <a href="https://www.igalia.com/">Igalia</a> made it possible to complete this crucial piece of core infrastructure for the etnaviv GPU stack.</p>
<p>If isaspec is new to you, here is what <a href="https://docs.mesa3d.org/isaspec.html">the Mesa docs</a> have to tell about it:</p>
<blockquote>
<p>isaspec provides a mechanism to describe an instruction set in XML, and generate a disassembler and assembler. The intention is to describe the instruction set more formally than hand-coded assembler and disassembler, and better decouple the shader compiler from the underlying instruction encoding to simplify dealing with instruction encoding differences between generations of GPU.</p>
<p>Benefits of a formal ISA description, compared to hand-coded assemblers and disassemblers, include easier detection of new bit combinations that were not seen before in previous generations due to more rigorous description of bits that are expect to be ‘0’ or ‘1’ or ‘x’ (dontcare) and verification that different encodings don’t have conflicting bits (i.e. that the specification cannot result in more than one valid interpretation of any bit pattern).</p>
</blockquote>
<p>If you are interested in more details, I highly recommend Rob Clark&rsquo;s <a href="https://www.youtube.com/watch?v=o0npIiIF-Dw">introduction to isaspec</a> presentation.</p>
<h1 id="target-isa">Target ISA</h1>
<p>Vivante uses a fixed-size (128 bits), predictable instruction format with explicit inputs and outputs.</p>
<p>As of today, there are three different encodings seen in the wild:</p>
<ul>
<li>Base Instruction Set</li>
<li>Extended Instruction Set</li>
<li>Enhanced Vision Instruction Set (EVIS)</li>
</ul>
<h1 id="why-do-i-want-to-switch-to-isaspec">Why do I want to switch to isaspec</h1>
<p>There are several reasons..</p>
<h2 id="the-current-state">The current state</h2>
<p>The <a href="https://github.com/etnaviv/etna_viv/blob/master/rnndb/isa.xml">current ISA documentation</a> is not very explicit and leaves lot of room for interpretation and speculation. One thing that it provides, are some nice explanations what an instruction does. isaspec does not support <code>&lt;doc&gt;</code> tags yet, but I there is a <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23763">PoC MR</a> that generates really nice looking and information ISA documentation based on the xml.</p>
<p>I think soon you might find all etnaviv&rsquo;s isaspec documentation at <a href="https://docs.mesa3d.org">docs.mesa3d.org</a>.</p>
<h2 id="no-unit-tests">No unit tests</h2>
<p>There are no unit tests based on instructions generated by the blob driver. This might not sound too bad, but it opens the door to generating &lsquo;bad&rsquo; encoded instructions that could trigger all sorts of weird and hard-to-debug problems. Such breakages could be caused by some compiler rework, etc.</p>
<p>In an ideal world, there would be a unit test that does the following:</p>
<ul>
<li>Disassembles the binary representation of an instruction from the blob to a string representation.</li>
<li>Verifies that it matches our expectation.</li>
<li>Assembles the string representation back to 128 bits.</li>
<li>Verifies that it matches the binary representation from the blob driver.</li>
</ul>
<p>This is our ultimate goal, which we <em>really</em> must reach. etnaviv will not be the only driver that does such deep unit testing - e.g. <a href="https://docs.mesa3d.org/drivers/freedreno.html">freedreno</a> <a href="https://cgit.freedesktop.org/mesa/mesa/tree/src/freedreno/ir3/tests/disasm.c#n581">does it too</a>.</p>
<h2 id="easier-to-understand-code">Easier to understand code</h2>
<p>Do you remember the rusticl OpenCL attempt for etnaviv? It contains lines like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl">      <span class="k">if</span> <span class="p">(</span><span class="nf">nir_src_is_const</span><span class="p">(</span><span class="n">intr</span><span class="o">-&gt;</span><span class="n">src</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">         <span class="n">inst</span><span class="p">.</span><span class="n">tex</span><span class="p">.</span><span class="n">swiz</span> <span class="o">=</span> <span class="mi">128</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="k">if</span> <span class="p">(</span><span class="n">rmode</span> <span class="o">==</span> <span class="n">nir_rounding_mode_rtz</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">         <span class="n">inst</span><span class="p">.</span><span class="n">tex</span><span class="p">.</span><span class="n">amode</span> <span class="o">=</span> <span class="mh">0x4</span> <span class="o">+</span> <span class="n">INST_ROUND_MODE_RTZ</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="k">else</span> <span class="cm">/*if (rmode == nir_rounding_mode_rtne)*/</span>
</span></span><span class="line"><span class="cl">         <span class="n">inst</span><span class="p">.</span><span class="n">tex</span><span class="p">.</span><span class="n">amode</span> <span class="o">=</span> <span class="mh">0x4</span> <span class="o">+</span> <span class="n">INST_ROUND_MODE_RTNE</span><span class="p">;</span>
</span></span></code></pre></div><p>Do you clearly see what is going on? Why do we need to set tex.amode for an ALU instruction?</p>
<p>I always found it quite disappointing to see such code snippets. Sure, they mimic what the blob driver is doing, but you might lose all the knowledge about why these bits are used that way days after you worked on it. There must be a cleaner, more understandable, and thus more maintainable way to document the ISA better.</p>
<p>This situation might become even worse if we want to support the other encodings and could end up with more of these bad patterns, resulting in a maintenance nightmare.</p>
<p>Oh, and if you wonder what happened to OpenCL and etnaviv - I promise there will be an update later this year.</p>
<h2 id="python-opens-the-door-to-generate-lot-of-code">Python opens the door to generate lot of code</h2>
<p>As isaspec is written in Python, it is really easy to extend it and add support for new functionality.</p>
<p>At its core, we can generate a disassembler and an assembler based on isaspec. This alone saves us from writing a lot of code that needs to be kept in sync with all the ISA reverse engineering findings that happen over time.</p>
<p>As isaspec is just an ordinary XML file, you can use any programming language you like to work with it.</p>
<h2 id="one-source-of-truth">One source of truth</h2>
<p>I really fell in love with the idea of having <em>one</em> source of truth that models our target ISA, contains written documentation, and extends each opcode with meta information that can be used in the upper layers of the compiler stack.</p>
<h1 id="missing-features">Missing Features</h1>
<p>I think I have sold you the idea quite well, so it must be a matter of some days to switch to it.
Sadly no, as there are some missing features:</p>
<ul>
<li>Only max 64 bits width ISAs are supported</li>
<li>Its home in src/freedreno</li>
<li>Alignment support is missing</li>
<li>No <code>&lt;meta&gt;</code> tags are supported</li>
</ul>
<h1 id="add-support-for-128-bit-wide-instructions">Add support for 128 bit wide instructions</h1>
<p>The first big <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11321">MR</a> I worked on, extended  <a href="https://cgit.freedesktop.org/mesa/mesa/tree/src/util/bitset.h">BITSET APIs</a> with features needed for isaspec.
Here we are talking about bitwise AND, OR, and NOT, and left shifts.</p>
<p>The next step was to switch isaspec to use the BITSET API to support wider ISAs. This resulted in a lot of commits, as there was a need for some new APIs to support handling this new feature. After these 31 commits, we were able to start looking into isaspec support for etnaviv.</p>
<h1 id="decode-support">Decode Support</h1>
<p>Now it is time to start writing an isaspec XML for etnaviv, and the easiest opcode to start with is the <code>nop</code>. As the name suggests, it does nothing and has no src&rsquo;s, no dst, or any other modifier.</p>
<p>As I do not have this initial version anymore, I tried to recreate it - it might have looked something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;isa&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;bitset</span> <span class="na">name=</span><span class="s">&#34;#instruction&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;display&gt;</span>
</span></span><span class="line"><span class="cl">		{NAME} void, void, void, void
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;/display&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;6&#34;</span> <span class="na">high=</span><span class="s">&#34;10&#34;</span><span class="nt">&gt;</span>00000<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;11&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;12&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;13&#34;</span> <span class="na">high=</span><span class="s">&#34;26&#34;</span><span class="nt">&gt;</span>00000000000000<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;27&#34;</span> <span class="na">high=</span><span class="s">&#34;31&#34;</span><span class="nt">&gt;</span>00000<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;32&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;33&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;34&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;35&#34;</span> <span class="na">high=</span><span class="s">&#34;38&#34;</span><span class="nt">&gt;</span>0000<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;39&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;40&#34;</span> <span class="na">high=</span><span class="s">&#34;42&#34;</span><span class="nt">&gt;</span>000<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c">&lt;!-- SRC0 --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;43&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC0_USE --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;44&#34;</span> <span class="na">high=</span><span class="s">&#34;52&#34;</span><span class="nt">&gt;</span>000000000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC0_REG --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;53&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;54&#34;</span> <span class="na">high=</span><span class="s">&#34;61&#34;</span><span class="nt">&gt;</span>00000000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC0_SWIZ --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;62&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC0_NEG --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;63&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC0_ABS --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;64&#34;</span> <span class="na">high=</span><span class="s">&#34;66&#34;</span><span class="nt">&gt;</span>000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC0_AMODE --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;67&#34;</span> <span class="na">high=</span><span class="s">&#34;69&#34;</span><span class="nt">&gt;</span>000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC0_RGROUP --&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c">&lt;!-- SRC1 --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;70&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC1_USE --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;71&#34;</span> <span class="na">high=</span><span class="s">&#34;79&#34;</span><span class="nt">&gt;</span>000000000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC1_REG --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;81&#34;</span> <span class="na">high=</span><span class="s">&#34;88&#34;</span><span class="nt">&gt;</span>00000000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC1_SWIZ --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;89&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC1_NEG --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;90&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC1_ABS --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;91&#34;</span> <span class="na">high=</span><span class="s">&#34;93&#34;</span><span class="nt">&gt;</span>000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC1_AMODE --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;94&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;95&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;96&#34;</span> <span class="na">high=</span><span class="s">&#34;98&#34;</span><span class="nt">&gt;</span>000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC1_RGROUP --&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c">&lt;!-- SRC2 --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;99&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC2_USE --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;100&#34;</span> <span class="na">high=</span><span class="s">&#34;108&#34;</span><span class="nt">&gt;</span>000000000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC2_REG --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;110&#34;</span> <span class="na">high=</span><span class="s">&#34;117&#34;</span><span class="nt">&gt;</span>00000000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC2_SWIZ --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;118&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC2_NEG --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;119&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC2_ABS --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;120&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;121&#34;</span> <span class="na">high=</span><span class="s">&#34;123&#34;</span><span class="nt">&gt;</span>000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC2_AMODE --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;124&#34;</span> <span class="na">high=</span><span class="s">&#34;126&#34;</span><span class="nt">&gt;</span>000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- SRC2_RGROUP --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;127&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/bitset&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c">&lt;!-- opcocdes sorted by opc number --&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nt">&lt;bitset</span> <span class="na">name=</span><span class="s">&#34;nop&#34;</span> <span class="na">extends=</span><span class="s">&#34;#instruction&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">low=</span><span class="s">&#34;0&#34;</span> <span class="na">high=</span><span class="s">&#34;5&#34;</span><span class="nt">&gt;</span>000000<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- OPC --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;pattern</span> <span class="na">pos=</span><span class="s">&#34;80&#34;</span><span class="nt">&gt;</span>0<span class="nt">&lt;/pattern&gt;</span> <span class="c">&lt;!-- OPCODE_BIT6 --&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/bitset&gt;&lt;/isa&gt;</span>
</span></span></code></pre></div><p>With the knowledge of the old ISA documentation, I went fishing for instructions. I <em>only</em> used instructions from the binary blob for this process. It is quite important for me to have as many unit tests as I can write to not break any decoding with some isaspec XML changes I do. And it was a huge lifesaver at that time.</p>
<p>After I reached almost feature parity with the old disassembler, I thought it was time to land etnaviv.xml and replace the current handwritten disassembler with a generated one - yeah, so I submitted <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20144">an MR</a> to make the switch.</p>
<p>As this is only a driver internal disassembler used by maybe 2-3 human beings, it would not be a problem if there were some regressions.</p>
<p>Today I would say the isaspec disassembler is superior to the handwritten one.</p>
<h1 id="encode-support">Encode Support</h1>
<p>The next item on my list was to add encoding support. As you can imagine, there was some work needed upfront to support ISAs that are bigger than 64 bits.  This time the <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16996">MR</a> only contains two commits 😄.</p>
<p>With everything ready it is time to add <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28183">isaspec based encoding support to etnaviv.</a></p>
<p>The goal is to drop our custom (and too simple) assembler and switch to one that is powered by isaspec.</p>
<p>This opens the door to:</p>
<ul>
<li>Modeling special cases for instructions like a branch with no src&rsquo;s to a new jump instruction.</li>
<li>Doing the NIR src -&gt; instruction src mapping in isaspec.</li>
<li>Supporting different instruction encodings.</li>
<li>Adding meta information to instructions.</li>
</ul>
<h1 id="supporting-special-instructions-that-are-used-in-compiler-unit-tests">Supporting special instructions that are used in compiler unit tests</h1>
<p>In the end, all the magic that is needed is shown in the following diff:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-patch" data-lang="patch"><span class="line"><span class="cl"><span class="gh">diff --git a/src/etnaviv/isa/etnaviv.xml b/src/etnaviv/isa/etnaviv.xml
</span></span></span><span class="line"><span class="cl"><span class="gh">index eca8241a2238a..c9a3ebe0a40c2 100644
</span></span></span><span class="line"><span class="cl"><span class="gd">--- a/src/etnaviv/isa/etnaviv.xml
</span></span></span><span class="line"><span class="cl"><span class="gi">+++ b/src/etnaviv/isa/etnaviv.xml
</span></span></span><span class="line"><span class="cl"><span class="gu">@@ -125,6 +125,13 @@ SPDX-License-Identifier: MIT
</span></span></span><span class="line"><span class="cl"> 	&lt;field name=&#34;AMODE&#34; low=&#34;0&#34; high=&#34;2&#34; type=&#34;#reg_addressing_mode&#34;/&gt;
</span></span><span class="line"><span class="cl"> 	&lt;field name=&#34;REG&#34; low=&#34;3&#34; high=&#34;9&#34; type=&#34;uint&#34;/&gt;
</span></span><span class="line"><span class="cl"> 	&lt;field name=&#34;COMPS&#34; low=&#34;10&#34; high=&#34;13&#34; type=&#34;#wrmask&#34;/&gt;
</span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+	&lt;encode type=&#34;struct etna_inst_dst *&#34;&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;DST_USE&#34;&gt;p-&gt;DST_USE&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;AMODE&#34;&gt;src-&gt;amode&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;REG&#34;&gt;src-&gt;reg&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;COMPS&#34;&gt;p-&gt;COMPS&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+	&lt;/encode&gt;
</span></span></span><span class="line"><span class="cl"> &lt;/bitset&gt;
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"> &lt;bitset name=&#34;#instruction&#34; size=&#34;128&#34;&gt;
</span></span><span class="line"><span class="cl"><span class="gu">@@ -137,6 +144,46 @@ SPDX-License-Identifier: MIT
</span></span></span><span class="line"><span class="cl"> 	&lt;derived name=&#34;TYPE&#34; type=&#34;#type&#34;&gt;
</span></span><span class="line"><span class="cl"> 		&lt;expr&gt;{TYPE_BIT2} &amp;lt;&amp;lt; 2 | {TYPE_BIT01}&lt;/expr&gt;
</span></span><span class="line"><span class="cl"> 	&lt;/derived&gt;
</span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+	&lt;encode type=&#34;struct etna_inst *&#34; case-prefix=&#34;ISA_OPC_&#34;&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;TYPE_BIT01&#34;&gt;src-&gt;type &amp;amp; 0x3&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;TYPE_BIT2&#34;&gt;(src-&gt;type &amp;amp; 0x4) &amp;gt; 2&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;LOW_HALF&#34;&gt;src-&gt;sel_bit0&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;HIGH_HALF&#34;&gt;src-&gt;sel_bit1&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;COND&#34;&gt;src-&gt;cond&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;RMODE&#34;&gt;src-&gt;rounding&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SAT&#34;&gt;src-&gt;sat&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;DST_USE&#34;&gt;src-&gt;dst.use&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;DST&#34;&gt;&amp;amp;src-&gt;dst&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;DST_FULL&#34;&gt;src-&gt;dst_full&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;COMPS&#34;&gt;src-&gt;dst.write_mask&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC0&#34;&gt;&amp;amp;src-&gt;src[0]&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC0_USE&#34;&gt;src-&gt;src[0].use&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC0_REG&#34;&gt;src-&gt;src[0].reg&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC0_RGROUP&#34;&gt;src-&gt;src[0].rgroup&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC0_AMODE&#34;&gt;src-&gt;src[0].amode&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC1&#34;&gt;&amp;amp;src-&gt;src[1]&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC1_USE&#34;&gt;src-&gt;src[1].use&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC1_REG&#34;&gt;src-&gt;src[1].reg&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC1_RGROUP&#34;&gt;src-&gt;src[1].rgroup&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC1_AMODE&#34;&gt;src-&gt;src[1].amode&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC2&#34;&gt;&amp;amp;src-&gt;src[2]&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC2_USE&#34;&gt;rc-&gt;src[2].use&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC2_REG&#34;&gt;src-&gt;src[2].reg&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC2_RGROUP&#34;&gt;src-&gt;src[2].rgroup&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC2_AMODE&#34;&gt;src-&gt;src[2].amode&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;TEX_ID&#34;&gt;src-&gt;tex.id&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;TEX_SWIZ&#34;&gt;src-&gt;tex.swiz&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;TARGET&#34;&gt;src-&gt;imm&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;!-- sane defaults --&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;PMODE&#34;&gt;1&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SKPHP&#34;&gt;0&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;LOCAL&#34;&gt;0&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;DENORM&#34;&gt;0&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;LEFT_SHIFT&#34;&gt;0&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+	&lt;/encode&gt;
</span></span></span><span class="line"><span class="cl"> &lt;/bitset&gt;
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"> &lt;bitset name=&#34;#src-swizzle&#34; size=&#34;8&#34;&gt;
</span></span><span class="line"><span class="cl"><span class="gu">@@ -148,6 +195,13 @@ SPDX-License-Identifier: MIT
</span></span></span><span class="line"><span class="cl"> 	&lt;field name=&#34;SWIZ_Y&#34; low=&#34;2&#34; high=&#34;3&#34; type=&#34;#swiz&#34;/&gt;
</span></span><span class="line"><span class="cl"> 	&lt;field name=&#34;SWIZ_Z&#34; low=&#34;4&#34; high=&#34;5&#34; type=&#34;#swiz&#34;/&gt;
</span></span><span class="line"><span class="cl"> 	&lt;field name=&#34;SWIZ_W&#34; low=&#34;6&#34; high=&#34;7&#34; type=&#34;#swiz&#34;/&gt;
</span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+	&lt;encode type=&#34;uint8_t&#34;&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SWIZ_X&#34;&gt;(src &amp;amp; 0x03) &amp;gt;&amp;gt; 0&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SWIZ_Y&#34;&gt;(src &amp;amp; 0x0c) &amp;gt;&amp;gt; 2&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SWIZ_Z&#34;&gt;(src &amp;amp; 0x30) &amp;gt;&amp;gt; 4&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SWIZ_W&#34;&gt;(src &amp;amp; 0xc0) &amp;gt;&amp;gt; 6&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+	&lt;/encode&gt;
</span></span></span><span class="line"><span class="cl"> &lt;/bitset&gt;
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"> &lt;enum name=&#34;#thread&#34;&gt;
</span></span><span class="line"><span class="cl"><span class="gu">@@ -272,6 +326,13 @@ SPDX-License-Identifier: MIT
</span></span></span><span class="line"><span class="cl"> 			&lt;/expr&gt;
</span></span><span class="line"><span class="cl"> 		&lt;/derived&gt;
</span></span><span class="line"><span class="cl"> 	&lt;/override&gt;
</span></span><span class="line"><span class="cl"><span class="gi">+
</span></span></span><span class="line"><span class="cl"><span class="gi">+	&lt;encode type=&#34;struct etna_inst_src *&#34;&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC_SWIZ&#34;&gt;src-&gt;swiz&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC_NEG&#34;&gt;src-&gt;neg&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC_ABS&#34;&gt;src-&gt;abs&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+		&lt;map name=&#34;SRC_RGROUP&#34;&gt;p-&gt;SRC_RGROUP&lt;/map&gt;
</span></span></span><span class="line"><span class="cl"><span class="gi">+	&lt;/encode&gt;
</span></span></span><span class="line"><span class="cl"> &lt;/bitset&gt;
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl"> &lt;bitset name=&#34;#instruction-alu-no-src&#34; extends=&#34;#instruction-alu&#34;&gt;
</span></span></code></pre></div><p>One nice side effect of this work is the removal of <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=6b1456ccdbccedaa3342fd1a7a0a6fbba26df49b">isa.xml.h</a> file that has been part of etnaviv since day one. We are able to generate all the file contents with isaspec and some custom python3 scripts. The move <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28922">of instruction src swizzling</a> from the driver into etnaviv.xml was super easy - less code to maintain!</p>
<h1 id="summary">Summary</h1>
<p>I am really happy with the end result, even though it took quite some time from the initial idea to the point when everything was integrated into Mesa&rsquo;s main git branch.</p>
<p>There is so much more to share - I can&rsquo;t wait to publish parts II and III.</p>
]]></content:encoded>
    </item>
    <item>
      <title>hwdb - The only truth</title>
      <link>https://christian-gmeiner.info/2024-04-12-hwdb/</link>
      <pubDate>Fri, 12 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2024-04-12-hwdb/</guid>
      <description>&lt;p&gt;Trusting hardware, particularly the registers that describe its functionality, is fundamentally risky.&lt;/p&gt;
&lt;h1 id=&#34;tldr&#34;&gt;tl;dr&lt;/h1&gt;
&lt;p&gt;The etnaviv GPU stack is continuously improving and becoming more robust. This time, a hardware database was incorporated into Mesa, utilizing header files provided by the SoC vendors.&lt;/p&gt;
&lt;p&gt;If you are interested in the implementation details, I recommend checking out this &lt;a href=&#34;https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28574&#34;&gt;Mesa MR&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Are you employed at &lt;a href=&#34;https://www.verisilicon.com/&#34;&gt;Versilicon&lt;/a&gt; and want to help? You could greatly simplify our work by supplying the community with a comprehensive header that includes all the models you offer.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Trusting hardware, particularly the registers that describe its functionality, is fundamentally risky.</p>
<h1 id="tldr">tl;dr</h1>
<p>The etnaviv GPU stack is continuously improving and becoming more robust. This time, a hardware database was incorporated into Mesa, utilizing header files provided by the SoC vendors.</p>
<p>If you are interested in the implementation details, I recommend checking out this <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28574">Mesa MR</a>.</p>
<p>Are you employed at <a href="https://www.verisilicon.com/">Versilicon</a> and want to help? You could greatly simplify our work by supplying the community with a comprehensive header that includes all the models you offer.</p>
<p>Last but not least: I deeply appreciate <a href="https://www.igalia.com/">Igalia</a>&rsquo;s passion for open source GPU driver development, and I am grateful to be a part of the team. Their enthusiasm for open source work not only pushes the boundaries of technology but also builds a strong, collaborative community around it.</p>
<h1 id="the-good-old-days">The good old days</h1>
<p>Years ago, when I began dedicating time to hacking on etnaviv, the kernel driver in use would read a handful of registers and relay the gathered information to the user space blob. This blob driver was then capable of identifying the GPU (including model, revision, etc.), supported features (such as DXT texture compression, seamless cubemaps, etc.), and crucial limits (like the number of registers, number of varyings, and so on).</p>
<p>For reverse engineering purposes, this interface is super useful. Image if you could change one of these feature bits on a target running the binary blob.</p>
<p>With <a href="https://github.com/etnaviv/libvivhook">libvivhook</a> it is possible to do exactly this. From time to time, I am running such an old vendor driver stack on an i.MX 6QuadPlus SBC, which features a Vivante GC3000 as its GPU.</p>
<p>Somewhere, I have a collection of scripts that I utilized to acquire additional knowledge about unknown GPU states activated when a specific feature bit was set.</p>
<p>To explore a simple example, let&rsquo;s consider the case of misrepresenting a GPU&rsquo;s identity as a GC2000. This involves modifying the information provided by the kernel driver to the user space, making the user space driver believe it is interacting with a GC2000 GPU. This scenario could be used for testing, debugging, or understanding how specific features or optimizations are handled differently across GPU models.</p>
<pre tabindex="0"><code>export ETNAVIV_CHIP_MODEL=&#34;0x2000&#34;
export ETNAVIV_CHIP_REVISION=&#34;0x5108&#34;
export ETNAVIV_FEATURES0_CLEAR=&#34;0xFFFFFFFF&#34;
export ETNAVIV_FEATURES1_CLEAR=&#34;0xFFFFFFFF&#34;
export ETNAVIV_FEATURES2_CLEAR=&#34;0xFFFFFFFF&#34;
export ETNAVIV_FEATURES0_SET=&#34;0xe0296cad&#34;
export ETNAVIV_FEATURES1_SET=&#34;0xc9799eff&#34;
export ETNAVIV_FEATURES2_SET=&#34;0x2efbf2d9&#34;
LD_PRELOAD=&#34;/lib/viv_interpose.so&#34; ./test-case
</code></pre><p>If you capture the generated command stream and compare it with the one produced under the correct identity, you&rsquo;ll observe many differences. This is super useful - I love it.</p>
<h1 id="changing-tides-the-shift-in-ioctl-interface">Changing Tides: The Shift in ioctl() Interface</h1>
<p>At some point in time, Vivante changed their ioctl() interface and modified the <code>gcvHAL_QUERY_CHIP_IDENTITY</code> command. Instead of providing a very detailed chip identity, they reduced the data set to the following values:</p>
<ul>
<li>model</li>
<li>revision</li>
<li>product id</li>
<li>eco id</li>
<li>customer id</li>
</ul>
<p>This shift could indeed hinder reverse engineering efforts significantly. At a glance, it becomes impossible to alter any feature value, and understanding how the vendor driver processes these values is out of reach. Determining the function or impact of an unknown feature bit now seems unattainable.</p>
<p>However, the kernel driver also requires a mechanism to verify the existing features of the GPU, as it needs to accommodate a wide variety of GPUs. Therefore, there must be some sort of system or method in place to ensure the kernel driver can effectively manage and support the diverse functionalities and capabilities of different GPUs.</p>
<h1 id="a-new-approach-the-hardware-database-dilemma">A New Approach: The Hardware Database Dilemma</h1>
<p>Let&rsquo;s welcome: gc_feature_database.h, or hwdb for short.</p>
<p>Vivante transitioned to using a database that stores entries for limit values and feature bits. This database is accessed by querying with model, revision, product id, eco id and customer id.</p>
<p>There is some speculation why this move was done. My theory posits that they became frustrated with the recurring cycle of introducing feature bits to indicate the implementation of a feature, subsequently discovering problems with said feature, and then having to introduce additional feature bits to signal that the feature now truly operates as intended. It became far more straightforward to deactivate a malfunctioning feature by modifying information in the hardware database (hwdb). After they began utilizing the hwdb within the driver, updates to the feature registers in the hardware ceased.</p>
<p>Here is a concrete example of such a case that can be found in the <a href="https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/etnaviv/etnaviv_screen.c?h=24.0#n1029">etnaviv gallium driver</a>:</p>
<pre tabindex="0"><code>screen-&gt;specs.tex_astc = VIV_FEATURE(screen, chipMinorFeatures4, TEXTURE_ASTC) &amp;&amp;
                            !VIV_FEATURE(screen, chipMinorFeatures6, NO_ASTC);
</code></pre><p>Meanwhile, in the etnaviv world there was a hybrid in the making. We stuck with the detailed <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/drm/etnaviv_drm.h?h=v6.8#n51">feature words</a> and found a smart way to convert from Vivante&rsquo;s hwdb entries to our own <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c?h=v6.8">in-kernel database</a>. There is even a <a href="https://github.com/gizmo98/hwdb-converter">full blown</a> Vivante -&gt; etnaviv hwdb convert.</p>
<p>At that time, I did not fully understand all the consequences this approach would bring - more on that later. So, I dedicated my free time to reverse engineering and tweaking the user space driver, while letting the kernel developers do their thing.</p>
<p>About a year after the <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/gpu/drm/etnaviv?h=v6.8&amp;id=681c19c8bf34df58e6705ba4c1a1676474ef7799">initial hwdb</a> landed in the kernel, I thought it might be a good idea to <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=815e45bbd4d3b00ddb2af017fbdab25110ed13a4">read out the extra id values</a>, and <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=000806631d2a0bc914ffcf2a72aeb6dd59c7fc11">provide them via sysfs</a> to <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1ff79a4a49c239dedd67a12a16a8c3a8b53cf838">the user space</a>. At that time, I already had the idea of moving the hardware database to user space in mind. However, I was preoccupied with other priorities that were higher on my to-do list, and I ended up forgetting about it.</p>
<h1 id="challange-accepted">Challange accepted</h1>
<p><a href="https://blog.tomeuvizoso.net/">Tomeu Vizoso</a> began to work on <a href="https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/frontends/teflon">teflon</a> and a Neural Processing Unit (NPU) driver within Mesa, leveraging a significant amount of the existing codebase and concepts, including the same kernel driver for the GPU. During this process, he encountered a need for some NPU-specific limit values. To address this, he added an <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=49b5ff4c11305dec03e94490071931bf85981f65">in-kernel hwdb entry</a> and <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1dccdba084897443d116508a8ed71e0ac8a031a4">made the limit values accessible to user space</a>.</p>
<p>That&rsquo;s it — the kernel supplies all the values the NPU driver requires. We&rsquo;re finished, aren&rsquo;t we?</p>
<p>It turns out, that there are <a href="https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27513#note_2274394">many more NPU related</a> values that need to be exposed in the same manner, with seemingly no end in sight.</p>
<p>One of the major drawbacks when the hardware database (hwdb) resides in the kernel is the considerable amount of time it takes for hwdb patches to be written, reviewed, and eventually merged into Linus&rsquo;s git tree. This significantly slows down the development of user space drivers. For end users, this means they must either run a bleeding-edge kernel or backport the necessary changes on their own.</p>
<p>For me personally, the in-kernel hardware database should never have been implemented in its current form. If I could go back in time, I would have voiced my concerns.</p>
<p>As a result, moving the hardware database (hwdb) to user space quickly became a top priority on my to-do list, and I began working on it. However, during the testing phase of my proof of concept (PoC), I had to pause my work due to a kernel issue that made it unreliable for user space to trust the ID values provided by the kernel. Once <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b735ee173f84d5d0d0733c53946a83c12d770d05">my fix for this issue</a> began to be incorporated into stable kernel versions, it was time to finalize the user space hwdb.</p>
<p>There is only one little but important detail we have not talked about yet. There are vendor specific versions of gc_feature_database.h based on different versions of the binary blob. For instance, there is one from <a href="https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/drivers/mxc/gpu-viv/hal/kernel/inc/gc_feature_database.h">NXP</a>, <a href="https://github.com/STMicroelectronics/gcnano-binaries/blob/gcnano-6.4.13-binaries/gcnano-driver-stm32mp/hal/kernel/inc/gc_feature_database.h">ST</a>, <a href="https://github.com/khadas/android_vendor_amlogic_common_npu/blob/khadas-vim4-r-64bit/hal/kernel/inc/gc_feature_database.h">Amlogic</a> and some more.</p>
<p>Here is a brief look at the differences:</p>
<pre tabindex="0"><code>nxp/gc_feature_database.h (autogenerated at 2023-10-24 16:06:00, 861 struct members, 27 entries)
stm/gc_feature_database.h (autogenerated at 2022-12-29 11:13:00, 833 struct members, 4 entries)
amlogic/gc_feature_database.h (autogenerated at 2021-04-12 17:20:00, 733 struct members, 8 entries)
</code></pre><p>We understand that these header files are generated and adhere to a specific structure. Therefore, all we need to do is write an intelligent Python script capable of merging the struct members into a single consolidated struct. This script will also convert the old struct entries to the new format and generate a header file that we can use.</p>
<p>I&rsquo;m consistently amazed by how swiftly and effortlessly Python can be used for such tasks. Ninety-nine percent of the time, there&rsquo;s a ready-to-use Python module available, complete with examples and some documentation. To address the C header parsing challenge, I opted for <a href="https://github.com/eliben/pycparser">pycparser</a>.</p>
<p>The final outcome is a generated hwdb.h file that looks and feels similar to those generated from the binary blob.</p>
<h1 id="future-proof">Future proof</h1>
<p>This header merging approach offers several advantages:</p>
<ul>
<li>It simplifies the support for another SoC vendor.</li>
<li>There&rsquo;s no need to comprehend the significance of each feature bit.</li>
<li>The source header files are supplied by Versilicon or the SoC vendor, ensuring accuracy.</li>
<li>Updating the hwdb is straightforward — simply replace the files and rebuild Mesa.</li>
<li>It allows for much quicker deployment of new features and hwdb updates since no kernel update is required.</li>
<li>This method accelerates the development of user space drivers.</li>
</ul>
<p>While working on this topic I decided to do a bigger refactoring with the end goal to provide a <code>struct etna_core_info</code> that is located outside of the gallium driver.</p>
<p>This makes the code future proof and moves the filling of <code>struct etna_core_info</code> directly into the lowest layer - libetnaviv_drm (<a href="https://cgit.freedesktop.org/mesa/mesa/tree/src/etnaviv/drm">src/etnaviv/drm</a>).</p>
<p>We have not yet talked about one important detail.</p>
<blockquote>
<p>What happens if there is no entry in the user space hwdb?</p>
</blockquote>
<p>The solution is straightforward: we fallback to the previous method and request all feature words from the kernel driver. However, in an ideal scenario, our user space hardware database should supply all necessary entries. If you find that an entry for your GPU/NPU is missing, please get in touch with me.</p>
<h1 id="what-about-the-in-kernel-hwdb">What about the in-kernel hwdb?</h1>
<p>The existing system, despite its limitations, is set to remain indefinitely, with new entries being added to accommodate new GPUs. Although it will never contain as much information as the user space counterpart, this isn&rsquo;t necessarily a drawback. For the purposes at hand, only a handful of feature bits are required.</p>
]]></content:encoded>
    </item>
    <item>
      <title>The Year 2023 in Retrospect</title>
      <link>https://christian-gmeiner.info/2022-12-26-end-of-year/</link>
      <pubDate>Tue, 26 Dec 2023 09:03:20 -0800</pubDate>
      <guid>https://christian-gmeiner.info/2022-12-26-end-of-year/</guid>
      <description>&lt;p&gt;Holidays are here and I have time to look back at 2023. For six months I have been working for &lt;a href=&#34;https://www.igalia.com/&#34;&gt;Igalia&lt;/a&gt; and what should I say?&lt;/p&gt;
&lt;p&gt;I &amp;#x2764;&amp;#xfe0f; it!&lt;/p&gt;
&lt;p&gt;This was the best decision to leave my comfort zone of a normal 9-5 job. I am so proud to work on open source GPU drivers and I am able to spend much of my work time on etnaviv.&lt;/p&gt;
&lt;h2 id=&#34;driver-maintenance&#34;&gt;Driver maintenance&lt;/h2&gt;
&lt;p&gt;Before adding any new feature I thought it would be great idea to improve the current state of etnaviv&amp;rsquo;s gallium driver. Therefor I reworked some general driver &lt;a href=&#34;https://cgit.freedesktop.org/mesa/mesa/commit/?id=ae828a33a74c5b3fc6abee481eac7cb57bf815d0&#34;&gt;code&lt;/a&gt; to be more consistent and to have a more modern feeling, and made it possible to drop some &lt;a href=&#34;https://cgit.freedesktop.org/mesa/mesa/commit/?id=e13bdbbd5bfc1cef00cf504b0567238ae8f45524&#34;&gt;hand-rolled&lt;/a&gt; conversion helpers by switching to already existing solutions (&lt;code&gt;U_FIXED(..)&lt;/code&gt;, &lt;code&gt;S_FIXED(..)&lt;/code&gt;, &lt;code&gt;float_to_ubyte(..)&lt;/code&gt;).&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Holidays are here and I have time to look back at 2023. For six months I have been working for <a href="https://www.igalia.com/">Igalia</a> and what should I say?</p>
<p>I &#x2764;&#xfe0f; it!</p>
<p>This was the best decision to leave my comfort zone of a normal 9-5 job. I am so proud to work on open source GPU drivers and I am able to spend much of my work time on etnaviv.</p>
<h2 id="driver-maintenance">Driver maintenance</h2>
<p>Before adding any new feature I thought it would be great idea to improve the current state of etnaviv&rsquo;s gallium driver. Therefor I reworked some general driver <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=ae828a33a74c5b3fc6abee481eac7cb57bf815d0">code</a> to be more consistent and to have a more modern feeling, and made it possible to drop some <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=e13bdbbd5bfc1cef00cf504b0567238ae8f45524">hand-rolled</a> conversion helpers by switching to already existing solutions (<code>U_FIXED(..)</code>, <code>S_FIXED(..)</code>, <code>float_to_ubyte(..)</code>).</p>
<p>I worked through the low hanging fruits of crashes seen in CI runs and <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=add14d6cfb6b2aa666c7dbe2bbe43a8926d62d34">fixed</a> <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=a11501e014c82a51e606df079cc0dec2538fd860">many</a> of <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=9342544ca5c9ec2d7c100fe80f3cb6ac41547231">them</a>.</p>
<p>Feature wise, I also looked at some easy to implement extensions like <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=62e0f6bf328e37f3c4704ca35427c3dde0744977">GL_NV_conditional_render</a> and <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=dadb7244bb3df10b1418146b5a5c1cffa8364973">GL_OES_texture_half_float_linear</a>.</p>
<p>Besides the gallium driver I also worked on <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=fb48d3d1da0ab493fbd22f62dd85a9ab0c0811a0">some</a> <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=f831883af6389097624d0f9d8b067eb59b2c4780">NIR</a> and <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=2c9a59dcfc1fc5674a590f6d157f76ce57bd9cac">isaspec</a> <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=b2e4972339711a9576ec309ecdd4f42eb664c2f9">features</a> that are <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=fa0ff0849c5d96534195d276658aa8211d115076">beneficial</a> for etnaviv.</p>
<h2 id="xdc2023">XDC2023</h2>
<p>A personal highlight was to give a talk about etnaviv at XDC2023 <strong>in person</strong>.</p>
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/ZRAltAOUiuM?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>You might wonder what happened since mid October in etnaviv land.</p>
<h2 id="gles3">GLES3</h2>
<p>I worked on some features that are needed to expose GLES3 and it turned out that an easy to maintain, extend and test compiler backend is needed. Sadly etnaviv&rsquo;s current backend compiler does not check any of these boxes. It is so fragile that I only added some needed <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=5a952807487255cb8e3be6bc2eb66041f7f7785b">lowerings</a> to pass some of the <code>dEQP-GLES3.functional.shaders.texture_functions.*</code> tests.</p>
<p>Some more fun work regarding some feature emulation is on the horizon and it&rsquo;s blocked again by the current compiler.</p>
<h2 id="backend-compiler">Backend Compiler</h2>
<p>etnaviv includes an <a href="https://docs.mesa3d.org/isaspec.html">isaspec</a> powered <a href="https://cgit.freedesktop.org/mesa/mesa/commit/?id=64caf906328dad0491a07898cf4b6382f4baab35">disassembler</a> now - a small step towards a new backend compiler. Next on the road to success is the etnaviv backend IR with an assembler.</p>
<p>The new backend compiler is able to run OpenCL kernels with the help of rusticl but I want to land the new backend compiler in smaller chunks that are easier to review.</p>
<h2 id="multiple-render-targets">Multiple Render Targets</h2>
<p>During my XDC presentation I talked about a feature I got working on GC7000L - Multiple Render Targets (MRT). At this point it was more or less a proof-of-concept regarding the gallium drivers. There were some missing bits and register for full support on more GPU models and therefore more reverse engineering work was needed. Also the gallium driver needed lots of work to add support for MRT.</p>
<p>Some weeks later I had MRT working on a wider range of Vivante GPUs that are supporting this feature. This includes GC2000, GC3000 and GC7000 models among others. As etnaviv makes heavy use of GPU features it should work on even more models.</p>
<h2 id="looking-forward-to-2024">Looking forward to 2024</h2>
<p>I am really confident that we will see GLES3 and OpenCL for etnaviv. As driver testing is quite important for my work I will expand my current board farm and will look into the new star in CI world - <a href="https://gfx-ci.pages.freedesktop.org/ci-tron/">ci-tron</a>.</p>
<p>With that, have a happy holiday season and we&rsquo;ll be back with more improvements in 2024!</p>
]]></content:encoded>
    </item>
    <item>
      <title>Mainline kernel boot with STM32MP157C-DK2 Discovery Board</title>
      <link>https://christian-gmeiner.info/2019-12-19-stm32/</link>
      <pubDate>Thu, 19 Dec 2019 21:05:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2019-12-19-stm32/</guid>
      <description>&lt;p&gt;I recently bought a new device for my etnaviv board farm - &lt;a href=&#34;https://www.st.com/en/evaluation-tools/stm32mp157c-dk2.html&#34;&gt;STM32MP157C-DK2 Discovery Board&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The big problem is that the stock boot-chain can not boot a mainline kernel - it simply hangs.&lt;/p&gt;
&lt;h3 id=&#34;tf-a&#34;&gt;TF-A&lt;/h3&gt;
&lt;p&gt;Trusted Firmware-A (TF-A) is a reference implementation of secure-world software used on this platform. It implements a secure monitor with various interface standards:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The power state coordination interface (PSCI)&lt;/li&gt;
&lt;li&gt;Trusted board boot requirements (TBBR)&lt;/li&gt;
&lt;li&gt;SMC calling convention&lt;/li&gt;
&lt;li&gt;System control and management interface&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More information can be found at the official website at &lt;a href=&#34;https://www.trustedfirmware.org/&#34;&gt;https://www.trustedfirmware.org/&lt;/a&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I recently bought a new device for my etnaviv board farm - <a href="https://www.st.com/en/evaluation-tools/stm32mp157c-dk2.html">STM32MP157C-DK2 Discovery Board</a>.</p>
<p>The big problem is that the stock boot-chain can not boot a mainline kernel - it simply hangs.</p>
<h3 id="tf-a">TF-A</h3>
<p>Trusted Firmware-A (TF-A) is a reference implementation of secure-world software used on this platform. It implements a secure monitor with various interface standards:</p>
<ul>
<li>The power state coordination interface (PSCI)</li>
<li>Trusted board boot requirements (TBBR)</li>
<li>SMC calling convention</li>
<li>System control and management interface</li>
</ul>
<p>More information can be found at the official website at <a href="https://www.trustedfirmware.org/">https://www.trustedfirmware.org/</a>.</p>
<p>On kernel side when you need to access to secure feature (like clocks, resets &hellip;) you need to discuss it with this secure monitor using secure APIs. This APIs have not yet been pushed to mainline kernel. So It means that a mainline kernel can&rsquo;t access to secure resources and it is the reason for the boot hang.</p>
<h3 id="u-boot---the-solution">u-boot - the solution</h3>
<p>It looks like that we can replace the current secure boot chain with u-boot in non-secure boot mode and call it a day.</p>
<script src="https://gist.github.com/austriancoder/5a78abf53c4c0b575d710ba2440dc901.js"></script>
<p>This will generate two build artifacts:</p>
<ul>
<li>u-boot-spl.stm32</li>
<li>u-boot.img</li>
</ul>
<p>Lets copy these artifacts with dd directly to the suitable partition. ST has a quite nice wiki where we can find some more <a href="https://wiki.st.com/stm32mpu/wiki/STM32MP15_TF-A#Update_via_SDCARD">details</a>.</p>
<ul>
<li>u-boot-spl.stm32 -&gt; fsbl1</li>
<li>u-boot.img -&gt; ssbl</li>
</ul>
<h3 id="lets-boot-it-">Lets boot it &hellip;</h3>
<p>Connect all your cables and have a look at you serial console:</p>
<script src="https://gist.github.com/austriancoder/4b6ea334925e3069d8e8a168034eb097.js"></script>
<p>And from there you can simply boot your mainline kernel:</p>
<script src="https://gist.github.com/austriancoder/3fa6756c6bda400089102f4a9cdb0fc7.js"></script>
]]></content:encoded>
    </item>
    <item>
      <title>Cloudflare DDNS and Unifi USG</title>
      <link>https://christian-gmeiner.info/2019-07-13-cloudflare-ddns-usg/</link>
      <pubDate>Sat, 13 Jul 2019 00:00:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2019-07-13-cloudflare-ddns-usg/</guid>
      <description>&lt;p&gt;This is a quick post for those of you looking for a completely free dynamic DNS solution for your home network running on Unifi.&lt;/p&gt;
&lt;p&gt;For years, I was a happy &lt;a href=&#34;https://dyn.com/dns&#34;&gt;DynDns&lt;/a&gt; user and even paid once for a premium plan. But now it is time for a change as I recently switched to &lt;a href=&#34;https://www.ui.com/&#34;&gt;Unfi&lt;/a&gt; network equipment including a &lt;a href=&#34;https://www.ui.com/unifi-routing/usg/&#34;&gt;USG&lt;/a&gt;. Currently, I am using &lt;a href=&#34;https://cloudflare.com&#34;&gt;Cloudflare&lt;/a&gt; for CDN, DDOS protection, free SSL certificates and DNS with a free account. Thankfully, Cloudflare has a free API that allows you to automatically update your DNS records.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>This is a quick post for those of you looking for a completely free dynamic DNS solution for your home network running on Unifi.</p>
<p>For years, I was a happy <a href="https://dyn.com/dns">DynDns</a> user and even paid once for a premium plan. But now it is time for a change as I recently switched to <a href="https://www.ui.com/">Unfi</a> network equipment including a <a href="https://www.ui.com/unifi-routing/usg/">USG</a>. Currently, I am using <a href="https://cloudflare.com">Cloudflare</a> for CDN, DDOS protection, free SSL certificates and DNS with a free account. Thankfully, Cloudflare has a free API that allows you to automatically update your DNS records.</p>
<h3 id="preparation-of-the-usg">Preparation of the USG</h3>
<p>The installed version of ddclient on the USG is too old to support Cloudflare&rsquo;s v4 API so we need to update it first.</p>
<script src="https://gist.github.com/austriancoder/ceee29fd6e4ca091490bfd74f5d10e33.js"></script>
<h3 id="configure-cloudflare-ddns-on-the-controller">Configure Cloudflare DDNS on the Controller</h3>
<p>With Controller version 5.10.25.0 it is not possible to configure Cloudflare DDNS via the UI, so we need to go another route. Luckily, the config.gateway.json is a file that sits in the UniFi Controller filesystem and allows custom changes to the USG that aren&rsquo;t available in the web GUI. For more [information visit Unifi <a href="https://help.ubnt.com/hc/en-us/articles/215458888-UniFi-USG-Advanced-Configuration">documentation here</a>.</p>
<script src="https://gist.github.com/austriancoder/4885d51580b76a38fd4d9b5256fb13c3.js"></script>
<p>After this step was done we are almost ready. Finally, we need to run a &ldquo;force provision&rdquo; to the USG in the UniFi Controller Devices &gt; USG &gt; Config &gt; Manage Device &gt; Force provision. That&rsquo;s it!</p>
<p>Keep in mind that chances are quite high that you might need to reupdate ddclient on the USG after an Firmware update.</p>
]]></content:encoded>
    </item>
    <item>
      <title>mesamatrix</title>
      <link>https://christian-gmeiner.info/2019-06-16-mesamatrix/</link>
      <pubDate>Sun, 16 Jun 2019 15:40:01 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2019-06-16-mesamatrix/</guid>
      <description>&lt;p&gt;You might be familiar with &lt;a href=&#34;https://mesamatrix.net/&#34;&gt;mesamatrix&lt;/a&gt; - a nice site to track the state of all GPU drivers provided by Mesa. Ohh.. did I say all? Let&amp;rsquo;s have a closer look:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This page is a graphical representation of the text file docs/features.txt from the Mesa repository.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So wouldn&amp;rsquo;t it be sick to get etnaviv mentioned in docs/features.txt and onto the matrix?&lt;/p&gt;
&lt;p&gt;First mesamatrix needs to know/support etnaviv. This seems to be quite simple as there is already a pull request to add a bunch of embedded GPU drivers: &lt;a href=&#34;https://github.com/MightyCreak/mesamatrix/pull/136&#34;&gt;Add VC4,VC5 and Vivante GPUs&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>You might be familiar with <a href="https://mesamatrix.net/">mesamatrix</a> - a nice site to track the state of all GPU drivers provided by Mesa. Ohh.. did I say all? Let&rsquo;s have a closer look:</p>
<blockquote>
<p>This page is a graphical representation of the text file docs/features.txt from the Mesa repository.</p>
</blockquote>
<p>So wouldn&rsquo;t it be sick to get etnaviv mentioned in docs/features.txt and onto the matrix?</p>
<p>First mesamatrix needs to know/support etnaviv. This seems to be quite simple as there is already a pull request to add a bunch of embedded GPU drivers: <a href="https://github.com/MightyCreak/mesamatrix/pull/136">Add VC4,VC5 and Vivante GPUs</a></p>
<p><img alt="Comment found at mesamatrix pull request" loading="lazy" src="/img/mesamatrix_pull_20190616.png"></p>
<p>Second we need is to add support for an easy to support extension. After skimming through the list I settled with <a href="https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_seamless_cubemap_per_texture.txt">ARB_seamless_cubemap_per_texture</a></p>
<p>To be fair I know that there are some UNK bits in the sampler registers and I hope one of them has something to do with seamless cubemaps. I went with a quick try-and-error approach to find the UNK bit which enables seamless cubemaps. And after 20 minutes of hacking the spec@amd_seamless_cubemap_per_texture@amd_seamless_cubemap_per_texture piglit works \o/.</p>
<p>The end result can be found in <a href="https://gitlab.freedesktop.org/mesa/mesa/merge_requests/997">in this merge request</a>. I hope to merge the changes soon and see something new in mesamatrix.</p>
]]></content:encoded>
    </item>
    <item>
      <title>device-tree introspection</title>
      <link>https://christian-gmeiner.info/2017-09-20-device-tree-introspection/</link>
      <pubDate>Wed, 20 Sep 2017 19:13:01 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2017-09-20-device-tree-introspection/</guid>
      <description>&lt;p&gt;From time to time I need to inspect a used device-tree of a running device. For instance, the used bootloader (u-boot, barebox, &amp;hellip;) patches the the initial specified dtb and I want to see the modified one. All that is needed is an installed device-tree-compiler on the target.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ dtc -I fs -O dts /sys/firmware/devicetree/base
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <content:encoded><![CDATA[<p>From time to time I need to inspect a used device-tree of a running device. For instance, the used bootloader (u-boot, barebox, &hellip;) patches the the initial specified dtb and I want to see the modified one. All that is needed is an installed device-tree-compiler on the target.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ dtc -I fs -O dts /sys/firmware/devicetree/base
</span></span></code></pre></div>]]></content:encoded>
    </item>
    <item>
      <title>etnaviv officially landed</title>
      <link>https://christian-gmeiner.info/2017-01-12-etnaviv-officially-landed-in-mesa/</link>
      <pubDate>Thu, 12 Jan 2017 19:48:36 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2017-01-12-etnaviv-officially-landed-in-mesa/</guid>
      <description>&lt;p&gt;After years of hard work the etnaviv team reached an other very important milestone. The gallium driver and the renderonly library got pushed into mesa&amp;rsquo;s git repository and will be released with mesa 17.0 - yeah!&lt;/p&gt;
&lt;p&gt;This does not mean we are done with development at all. There are many interesting topics to work on and some of them like better support for newer IP cores or a reworked GLSL compiler should see the light of day during the next months.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>After years of hard work the etnaviv team reached an other very important milestone. The gallium driver and the renderonly library got pushed into mesa&rsquo;s git repository and will be released with mesa 17.0 - yeah!</p>
<p>This does not mean we are done with development at all. There are many interesting topics to work on and some of them like better support for newer IP cores or a reworked GLSL compiler should see the light of day during the next months.</p>
<p>I think 2017 will be a quite interesting one for etnaviv and open source GPU drivers in general.</p>
<p>At this point I want to thank a lot of people who helped out in different areas. The whole <a href="http://www.mesa3d.org">mesa community</a> (esp. Rob, Ilia and Emil), <a href="https://www.solid-run.com/">SolidRun</a> for provided hardware, <a href="http://www.pengutronix.com">Pengutronix</a> - the &lsquo;imx6-company&rsquo; - for doing a wonderful job in the kernel space and all the other guys I meet in real life or via irc/mail.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Let’s Encrypt</title>
      <link>https://christian-gmeiner.info/2016-01-30-lets-encrypt/</link>
      <pubDate>Sat, 30 Jan 2016 21:58:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2016-01-30-lets-encrypt/</guid>
      <description>&lt;p&gt;As HTTPS is a must nowadays I decided a year a go to give it a try and got a certificate from &lt;a href=&#34;https://www.startssl.com/&#34;&gt;startssl&lt;/a&gt;. The process at startssl took quite some time and was not that easy. With &lt;a href=&#34;https://letsencrypt.org&#34;&gt;lets encrypt&lt;/a&gt; everything should be much easier and faster to setup – lets give it a try @&lt;a href=&#34;https://uberspace.de/&#34;&gt;ueberspace&lt;/a&gt; (my hoster).&lt;/p&gt;
&lt;p&gt;There is a very good (German) &lt;a href=&#34;https://funkenstrahlen.de/blog/2015/12/19/lets-encrypt-auf-uberspace/&#34;&gt;tutorial directly from ueberspace&lt;/a&gt; for the whole process. Two minutes later everything was done and it worked! There is only one missing part. As the generated certificate is only valid for 90 days I created a little script which gets run every month – thanks to cron.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>As HTTPS is a must nowadays I decided a year a go to give it a try and got a certificate from <a href="https://www.startssl.com/">startssl</a>. The process at startssl took quite some time and was not that easy. With <a href="https://letsencrypt.org">lets encrypt</a> everything should be much easier and faster to setup – lets give it a try @<a href="https://uberspace.de/">ueberspace</a> (my hoster).</p>
<p>There is a very good (German) <a href="https://funkenstrahlen.de/blog/2015/12/19/lets-encrypt-auf-uberspace/">tutorial directly from ueberspace</a> for the whole process. Two minutes later everything was done and it worked! There is only one missing part. As the generated certificate is only valid for 90 days I created a little script which gets run every month – thanks to cron.</p>
<div class="oembed-gist"><script src="https://gist.github.com/austriancoder/911ca10c26dd24ac6b585ad4a62242a6.js"></script><noscript>View the code on [Gist](https://gist.github.com/austriancoder/911ca10c26dd24ac6b585ad4a62242a6).</noscript></div>
]]></content:encoded>
    </item>
    <item>
      <title>etnaviv: kmscube</title>
      <link>https://christian-gmeiner.info/2015-09-25-etnaviv-kmscube/</link>
      <pubDate>Fri, 25 Sep 2015 21:39:10 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2015-09-25-etnaviv-kmscube/</guid>
      <description>&lt;p&gt;Last Friday I got kmscube successfully running with mesa and the new etnaviv DRM kernel driver. At this time I got it not really pixel perfect and I spend some nights to get it fixed. It turns out that I need a small mesa hack to get the rendering correct.&lt;/p&gt;
&lt;iframe allowfullscreen=&#34;&#34; frameborder=&#34;0&#34; height=&#34;473&#34; src=&#34;https://www.youtube.com/embed/vjIBow3M-C4?feature=oembed&#34; width=&#34;840&#34;&gt;&lt;/iframe&gt;
&lt;p&gt;You may ask why did it so long to get it working? Let me explain it to you.&lt;/p&gt;
&lt;p&gt;The Vivnate GPU is a so called render-only GPU which does not have any kind of scanout logic in it. It can only render to physical memory and this only in a tiled memory layout. So we need to use the resolve engine found on the GPU to de-tile the rendered image and blit it to the dumb buffer. Currently mesa has  no software support for this kind of hardware, but I think that could change soon.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Last Friday I got kmscube successfully running with mesa and the new etnaviv DRM kernel driver. At this time I got it not really pixel perfect and I spend some nights to get it fixed. It turns out that I need a small mesa hack to get the rendering correct.</p>
<iframe allowfullscreen="" frameborder="0" height="473" src="https://www.youtube.com/embed/vjIBow3M-C4?feature=oembed" width="840"></iframe>
<p>You may ask why did it so long to get it working? Let me explain it to you.</p>
<p>The Vivnate GPU is a so called render-only GPU which does not have any kind of scanout logic in it. It can only render to physical memory and this only in a tiled memory layout. So we need to use the resolve engine found on the GPU to de-tile the rendered image and blit it to the dumb buffer. Currently mesa has  no software support for this kind of hardware, but I think that could change soon.</p>
<p>I think that this is a huge step into the right direction. All the needed sources can be found on <a href="https://github.com/austriancoder">my github account</a>. At the moment I am cleaning up the code and shortly I will send out RFC patch series for <strike>libdrm and</strike> mesa. Currently some hacks are needed to get it up an running so there is still a lot left to do.</p>
<p><strike>Yes I think libdrm is needed and should not be part of the gallium driver. I even think xf86-video-armada could be using libdrm-etnaviv sooner or later. This one of the topics on my huge TODO list.</strike></p>
<p>Russell does not want to maintain a 3rd GPU backend and with that fact I think I will merge the etnaviv libdrm part directly into the driver. Let’s see how the patch series gets accepted.</p>
<p>I think this the perfect time to say “thank you” to some guys. Wladimir thanks for the wonderful code basis you provided for the whole etnaviv project. Rob, thanks for your patience with me – at this point in time I was a complete newbie in the mesa source code and the whole GPU world. Thanks NVIDIA for their wonderful render-only patch. Emil thanks for helping me out with ideas to get render-only into a working state. Also quite important for spare-time open source development is a hardware sponsor. In may case I want to thank <a href="http://solid-run.com/">SolidRun</a> for sending me two devices for etnaviv development purposes.</p>
]]></content:encoded>
    </item>
    <item>
      <title>QMetaEnum: Serializing C&#43;&#43; Enums</title>
      <link>https://christian-gmeiner.info/2015-05-25-qmetaenum-serializing-c-enums/</link>
      <pubDate>Mon, 25 May 2015 19:42:28 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2015-05-25-qmetaenum-serializing-c-enums/</guid>
      <description>&lt;p&gt;I think that almost every C++ programmer looked into a nice and easy way to do C++ Enum serialization. You may want to store the Enum value in a human readable format (json, ini, ..) and later you may also want to read back the value into the object.&lt;/p&gt;
&lt;p&gt;You have here two way how to archive your goal. Use simple int values to represent the Enum value or use Strings. The big advantage with strings it that you do not have to lookup what the meaning of value 4 is, but you can name the value with a String.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I think that almost every C++ programmer looked into a nice and easy way to do C++ Enum serialization. You may want to store the Enum value in a human readable format (json, ini, ..) and later you may also want to read back the value into the object.</p>
<p>You have here two way how to archive your goal. Use simple int values to represent the Enum value or use Strings. The big advantage with strings it that you do not have to lookup what the meaning of value 4 is, but you can name the value with a String.</p>
<p>Here I will present you with an non QObject based way of doing it in Qt5. You may wonder why I do not want to use a QObject as base for my class. The answer is quite simple. I need to be able to have a copy constructor and assignment operator for my class.</p>
<p>So lets start with the simple class Item which has Enum called Type in it.</p>
<div class="oembed-gist"><script src="https://gist.github.com/austriancoder/9bb0c0782aafa4bb1dbcc653e9442a33.js?file=item.h"></script><noscript>View the code on [Gist](https://gist.github.com/austriancoder/9bb0c0782aafa4bb1dbcc653e9442a33).</noscript></div>The big goal is to get Item::type() and Item::setType(QString) working as expected. Here is a small demo main(), which will be used for testing.
<div class="oembed-gist"><script src="https://gist.github.com/austriancoder/9bb0c0782aafa4bb1dbcc653e9442a33.js?file=main.cpp"></script><noscript>View the code on [Gist](https://gist.github.com/austriancoder/9bb0c0782aafa4bb1dbcc653e9442a33).</noscript></div>We exspect the following output:
<p>“APPLE”
“CAR”
“BIRD”</p>
<p>Here Qt’s MetaObject system comes to help. We use the MetaObject to get the correct QMetaEnum and make use of its valueToKey(..) and keyToValue(..) methods.</p>
<div class="oembed-gist"><script src="https://gist.github.com/austriancoder/9bb0c0782aafa4bb1dbcc653e9442a33.js?file=item.cpp"></script><noscript>View the code on [Gist](https://gist.github.com/austriancoder/9bb0c0782aafa4bb1dbcc653e9442a33).</noscript></div>In order to get this up and working we need to modify our header file.
<div class="oembed-gist"><script src="https://gist.github.com/austriancoder/9bb0c0782aafa4bb1dbcc653e9442a33.js?file=item_2.h"></script><noscript>View the code on [Gist](https://gist.github.com/austriancoder/9bb0c0782aafa4bb1dbcc653e9442a33).</noscript></div>The needed pars are here
<ul>
<li>Q_GADGET to get the processed by the meta object compiler (moc)</li>
<li>Q_ENUMS to ‘export’ the enum to the metaObject</li>
</ul>
<p>Qt’s MetaObject system saved my day and helped me to easily serialize C++ Enums in a very elegant way. The other more hacky solution would have been a big if-castle to check for each possible value and do everything on my own. But this could lead to problems if the Enum gets extended by an other developer not aware of the hand-written conversion methods.</p>
<p>All in all I am very happy with this solution.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Configure git send-email for gmail</title>
      <link>https://christian-gmeiner.info/2015-04-06-configure-git-send-email-for-gmail/</link>
      <pubDate>Mon, 06 Apr 2015 20:53:34 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2015-04-06-configure-git-send-email-for-gmail/</guid>
      <description>&lt;p&gt;Today I did a fresh installation of Fedora on my Chromebook and need to setup git send-email. Usually I need to do this step once every 1-2 years I thought it might be a good idea to write it down.&lt;/p&gt;
&lt;p&gt;Edit ~/.gitconfig&lt;/p&gt;
&lt;p&gt;[sendemail] from = Firstname Lastname &lt;a href=&#34;mailto:email@gmail.com&#34;&gt;email@gmail.com&lt;/a&gt; smtpserver = smtp.gmail.com smtpuser = &lt;a href=&#34;mailto:email@gmail.com&#34;&gt;email@gmail.com&lt;/a&gt; smtpencryption = tls smtppass = PASSWORD chainreplyto = false smtpserverport = 587&lt;/p&gt;
&lt;p&gt;As I am using Googles two factor authentication I needed to generate an app specific password.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Today I did a fresh installation of Fedora on my Chromebook and need to setup git send-email. Usually I need to do this step once every 1-2 years I thought it might be a good idea to write it down.</p>
<p>Edit ~/.gitconfig</p>
<p>[sendemail] from = Firstname Lastname <a href="mailto:email@gmail.com">email@gmail.com</a> smtpserver = smtp.gmail.com smtpuser = <a href="mailto:email@gmail.com">email@gmail.com</a> smtpencryption = tls smtppass = PASSWORD chainreplyto = false smtpserverport = 587</p>
<p>As I am using Googles two factor authentication I needed to generate an app specific password.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Fast forward to 2015</title>
      <link>https://christian-gmeiner.info/2015-03-08-fast-forward-to-2015/</link>
      <pubDate>Sun, 08 Mar 2015 18:16:20 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2015-03-08-fast-forward-to-2015/</guid>
      <description>&lt;p&gt;It has been a long time since I did the last post and I want to bring you up to date regarding my personal blog. As you might have seen I have changed the used theme to better support mobile devices.&lt;/p&gt;
&lt;p&gt;If your browser supports &lt;a href=&#34;http://en.wikipedia.org/wiki/Server_Name_Indication&#34;&gt;NSI&lt;/a&gt; you should access my blog via https now. It took me some time to setup everything but my new hoster &lt;a href=&#34;http://www.uberspace.de&#34;&gt;ueberspace&lt;/a&gt; made it a breeze to setup everything – thanks.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>It has been a long time since I did the last post and I want to bring you up to date regarding my personal blog. As you might have seen I have changed the used theme to better support mobile devices.</p>
<p>If your browser supports <a href="http://en.wikipedia.org/wiki/Server_Name_Indication">NSI</a> you should access my blog via https now. It took me some time to setup everything but my new hoster <a href="http://www.uberspace.de">ueberspace</a> made it a breeze to setup everything – thanks.</p>
<p>The biggest time safer for me is the switch to disqus comment system as it is quite time consuming to manage all the comments in the spam queue.</p>
<p>I hope you enjoy the new site and in the next blog I will talk about the current state of my biggest hobby project – etnaviv</p>
]]></content:encoded>
    </item>
    <item>
      <title>Vivante meets devicetree</title>
      <link>https://christian-gmeiner.info/2014-05-24-vivante-meets-devicetree/</link>
      <pubDate>Sat, 24 May 2014 23:41:14 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2014-05-24-vivante-meets-devicetree/</guid>
      <description>&lt;p&gt;It took me some time to rework the device tree bindings but it looks like it starts to work!&lt;/p&gt;
&lt;div class=&#34;oembed-gist&#34;&gt;&lt;script src=&#34;https://gist.github.com/austriancoder/6196fa33011a120a01dd54dbd077a60d.js&#34;&gt;&lt;/script&gt;&lt;noscript&gt;View the code on [Gist](https://gist.github.com/austriancoder/6196fa33011a120a01dd54dbd077a60d).&lt;/noscript&gt;&lt;/div&gt;Gets loaded into :
&lt;p&gt;[ 3.358155] vivante: module is from the staging directory, the quality is unknown, you have been warned.
[ 3.373087] imx-sgtl5000 sound.15: sgtl5000 2028000.ssi mapping ok
[ 3.379150] [drm] add child gpu2d
[ 3.379154] [drm] add child gpu3d
[ 3.380395] vivante-gpu 134000.gpu2d: pre gpu[idx]: 0x00000000
[ 3.380401] vivante-gpu 134000.gpu2d: adding core @idx 1
[ 3.380408] vivante-gpu 134000.gpu2d: post gpu[idx]: 0xecb56c10
[ 3.380460] vivante gpu-subsystem.11: bound 134000.gpu2d (ops gpu_ops [vivante])
[ 3.380467] vivante-gpu 130000.gpu3d: pre gpu[idx]: 0x00000000
[ 3.380473] vivante-gpu 130000.gpu3d: adding core @idx 0
[ 3.380479] vivante-gpu 130000.gpu3d: post gpu[idx]: 0xecb57210
[ 3.380502] vivante gpu-subsystem.11: bound 130000.gpu3d (ops gpu_ops [vivante])
[ 3.380533] IO:R f0200018 14010000
[ 3.380537] IO:R f0200020 00002000
[ 3.380540] IO:R f0200024 00005108
[ 3.380546] vivante gpu-subsystem.11: model: 2000
[ 3.380551] vivante gpu-subsystem.11: revision: 5108
[ 3.380554] IO:R f020001c e0296cad
[ 3.380558] IO:R f0200034 c9799eff
[ 3.380561] IO:R f0200074 2efbf2d9
[ 3.380564] IO:R f0200084 00000000
[ 3.380567] IO:R f0200088 00000000
[ 3.380572] vivante gpu-subsystem.11: minor_features: c9799eff
[ 3.380578] vivante gpu-subsystem.11: minor_features1: 2efbf2d9
[ 3.380583] vivante gpu-subsystem.11: minor_features2: 0
[ 3.380588] vivante gpu-subsystem.11: minor_features3: 0
[ 3.380592] IO:R f0200000 00070100
[ 3.408629] IO:R f0200004 7fffffff
[ 3.408632] IO:R f0200000 00070100
[ 3.412940] vivante gpu-subsystem.11: 130000.gpu3d: using IOMMU
[ 3.413080] IO:R f01f8018 14010000
[ 3.413083] IO:R f01f8020 00000320
[ 3.413087] IO:R f01f8024 00005007
[ 3.413093] vivante gpu-subsystem.11: model: 320
[ 3.413098] vivante gpu-subsystem.11: revision: 5007
[ 3.413101] IO:R f01f801c e02c7eca
[ 3.413105] IO:R f01f8034 c1399eff
[ 3.413108] IO:R f01f8074 020fb2db
[ 3.413111] IO:R f01f8084 00000000
[ 3.413114] IO:R f01f8088 00000000
[ 3.413120] vivante gpu-subsystem.11: minor_features: c1399eff
[ 3.413126] vivante gpu-subsystem.11: minor_features1: 20fb2db
[ 3.413131] vivante gpu-subsystem.11: minor_features2: 0
[ 3.413136] vivante gpu-subsystem.11: minor_features3: 0
[ 3.413139] IO:R f01f8000 00070100
[ 3.438615] IO:R f01f8004 7fffffff
[ 3.438619] IO:R f01f8000 00070100
[ 3.442583] vivante gpu-subsystem.11: 134000.gpu2d: using IOMMU
[ 3.442681] [drm] Initialized vivante 1.0.0 20130625 on minor 1&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>It took me some time to rework the device tree bindings but it looks like it starts to work!</p>
<div class="oembed-gist"><script src="https://gist.github.com/austriancoder/6196fa33011a120a01dd54dbd077a60d.js"></script><noscript>View the code on [Gist](https://gist.github.com/austriancoder/6196fa33011a120a01dd54dbd077a60d).</noscript></div>Gets loaded into :
<p>[ 3.358155] vivante: module is from the staging directory, the quality is unknown, you have been warned.
[ 3.373087] imx-sgtl5000 sound.15: sgtl5000 2028000.ssi mapping ok
[ 3.379150] [drm] add child gpu2d
[ 3.379154] [drm] add child gpu3d
[ 3.380395] vivante-gpu 134000.gpu2d: pre gpu[idx]: 0x00000000
[ 3.380401] vivante-gpu 134000.gpu2d: adding core @idx 1
[ 3.380408] vivante-gpu 134000.gpu2d: post gpu[idx]: 0xecb56c10
[ 3.380460] vivante gpu-subsystem.11: bound 134000.gpu2d (ops gpu_ops [vivante])
[ 3.380467] vivante-gpu 130000.gpu3d: pre gpu[idx]: 0x00000000
[ 3.380473] vivante-gpu 130000.gpu3d: adding core @idx 0
[ 3.380479] vivante-gpu 130000.gpu3d: post gpu[idx]: 0xecb57210
[ 3.380502] vivante gpu-subsystem.11: bound 130000.gpu3d (ops gpu_ops [vivante])
[ 3.380533] IO:R f0200018 14010000
[ 3.380537] IO:R f0200020 00002000
[ 3.380540] IO:R f0200024 00005108
[ 3.380546] vivante gpu-subsystem.11: model: 2000
[ 3.380551] vivante gpu-subsystem.11: revision: 5108
[ 3.380554] IO:R f020001c e0296cad
[ 3.380558] IO:R f0200034 c9799eff
[ 3.380561] IO:R f0200074 2efbf2d9
[ 3.380564] IO:R f0200084 00000000
[ 3.380567] IO:R f0200088 00000000
[ 3.380572] vivante gpu-subsystem.11: minor_features: c9799eff
[ 3.380578] vivante gpu-subsystem.11: minor_features1: 2efbf2d9
[ 3.380583] vivante gpu-subsystem.11: minor_features2: 0
[ 3.380588] vivante gpu-subsystem.11: minor_features3: 0
[ 3.380592] IO:R f0200000 00070100
[ 3.408629] IO:R f0200004 7fffffff
[ 3.408632] IO:R f0200000 00070100
[ 3.412940] vivante gpu-subsystem.11: 130000.gpu3d: using IOMMU
[ 3.413080] IO:R f01f8018 14010000
[ 3.413083] IO:R f01f8020 00000320
[ 3.413087] IO:R f01f8024 00005007
[ 3.413093] vivante gpu-subsystem.11: model: 320
[ 3.413098] vivante gpu-subsystem.11: revision: 5007
[ 3.413101] IO:R f01f801c e02c7eca
[ 3.413105] IO:R f01f8034 c1399eff
[ 3.413108] IO:R f01f8074 020fb2db
[ 3.413111] IO:R f01f8084 00000000
[ 3.413114] IO:R f01f8088 00000000
[ 3.413120] vivante gpu-subsystem.11: minor_features: c1399eff
[ 3.413126] vivante gpu-subsystem.11: minor_features1: 20fb2db
[ 3.413131] vivante gpu-subsystem.11: minor_features2: 0
[ 3.413136] vivante gpu-subsystem.11: minor_features3: 0
[ 3.413139] IO:R f01f8000 00070100
[ 3.438615] IO:R f01f8004 7fffffff
[ 3.438619] IO:R f01f8000 00070100
[ 3.442583] vivante gpu-subsystem.11: 134000.gpu2d: using IOMMU
[ 3.442681] [drm] Initialized vivante 1.0.0 20130625 on minor 1</p>
]]></content:encoded>
    </item>
    <item>
      <title>OpenOCD and the iMX6</title>
      <link>https://christian-gmeiner.info/2014-05-17-openocd-and-the-imx6/</link>
      <pubDate>Sat, 17 May 2014 17:24:35 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2014-05-17-openocd-and-the-imx6/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://christian-gmeiner.info/wp-content/uploads/2014/05/olimex.jpg&#34;&gt;&lt;img alt=&#34;olimex&#34; loading=&#34;lazy&#34; src=&#34;https://christian-gmeiner.info/wp-content/uploads/2014/05/olimex-768x1024.jpg&#34;&gt;&lt;/a&gt;
Sometimes is is quite handy to have access to a JTAG interface to look more deeply into problems.  The weapon of choice is an &lt;a href=&#34;https://www.olimex.com/Products/ARM/JTAG/ARM-USB-OCD-H/&#34;&gt;Olimex ARM-USB-OCD-H JTAG&lt;/a&gt; in combination with &lt;a href=&#34;http://openocd.sourceforge.net/&#34; title=&#34;OpenOCD&#34;&gt;OpenOCD&lt;/a&gt; 0.8.0.
First we will need to install OpenOCD.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;apt-get install libftdi-dev&lt;/li&gt;
&lt;li&gt;Download and extract OpenOCD 0.8.0&lt;/li&gt;
&lt;li&gt;run ./configure&lt;/li&gt;
&lt;li&gt;run make &amp;amp;&amp;amp; make install&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This should give you an OpenOCD installation with the following configuration:&lt;/p&gt;
&lt;p&gt;OpenOCD configuration summary &amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;ndash; MPSSE mode of FTDI based devices yes (auto) ST-Link JTAG Programmer yes (auto) TI ICDI JTAG Programmer yes (auto) Keil ULINK JTAG Programmer yes (auto) Altera USB-Blaster II Compatible yes (auto) Segger J-Link JTAG Programmer yes (auto) OSBDM (JTAG only) Programmer yes (auto) eStick/opendous JTAG Programmer yes (auto) Andes JTAG Programmer yes (auto) Versaloon-Link JTAG Programmer yes (auto) USBProg JTAG Programmer yes (auto) Raisonance RLink JTAG Programmer yes (auto) Olimex ARM-JTAG-EW Programmer yes (auto) CMSIS-DAP Compliant Debugger no&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><a href="/wp-content/uploads/2014/05/olimex.jpg"><img alt="olimex" loading="lazy" src="/wp-content/uploads/2014/05/olimex-768x1024.jpg"></a>
Sometimes is is quite handy to have access to a JTAG interface to look more deeply into problems.  The weapon of choice is an <a href="https://www.olimex.com/Products/ARM/JTAG/ARM-USB-OCD-H/">Olimex ARM-USB-OCD-H JTAG</a> in combination with <a href="http://openocd.sourceforge.net/" title="OpenOCD">OpenOCD</a> 0.8.0.
First we will need to install OpenOCD.</p>
<ol>
<li>apt-get install libftdi-dev</li>
<li>Download and extract OpenOCD 0.8.0</li>
<li>run ./configure</li>
<li>run make &amp;&amp; make install</li>
</ol>
<p>This should give you an OpenOCD installation with the following configuration:</p>
<p>OpenOCD configuration summary &mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&ndash; MPSSE mode of FTDI based devices yes (auto) ST-Link JTAG Programmer yes (auto) TI ICDI JTAG Programmer yes (auto) Keil ULINK JTAG Programmer yes (auto) Altera USB-Blaster II Compatible yes (auto) Segger J-Link JTAG Programmer yes (auto) OSBDM (JTAG only) Programmer yes (auto) eStick/opendous JTAG Programmer yes (auto) Andes JTAG Programmer yes (auto) Versaloon-Link JTAG Programmer yes (auto) USBProg JTAG Programmer yes (auto) Raisonance RLink JTAG Programmer yes (auto) Olimex ARM-JTAG-EW Programmer yes (auto) CMSIS-DAP Compliant Debugger no</p>
<p>Now its time to check if a debugger connection can be established. As the JTAG is usb based you should see it via lsusb.</p>
<p>Bus 002 Device 005: ID 15ba:002b Olimex Ltd. ARM-USB-OCD-H JTAG+RS232 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x15ba Olimex Ltd. idProduct 0x002b ARM-USB-OCD-H JTAG+RS232 bcdDevice 7.00 iManufacturer 1 Olimex iProduct 2 Olimex OpenOCD JTAG ARM-USB-OCD-H iSerial 3 OLWI19GT bNumConfigurations 1 [&hellip;]</p>
<p>At this point OpenOCD should be able to connect to the JTAG. For the beginning you only need to provide the interface and target scripts. In my case the following works.</p>
<p>christian@chgm-pc:~$ sudo openocd -f interface/ftdi/olimex-arm-usb-ocd-h.cfg -f target/imx6.cfg Open On-Chip Debugger 0.8.0 (2014-05-05-11:14) Licensed under GNU GPL v2 For bug reports, read <a href="http://openocd.sourceforge.net/doc/doxygen/bugs.html">http://openocd.sourceforge.net/doc/doxygen/bugs.html</a> Info : only one transport option; autoselect &lsquo;jtag&rsquo; Warn : imx6.sdma: nonstandard IR value adapter speed: 1000 kHz Info : clock speed 1000 kHz Info : JTAG tap: imx6.dap tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4) Info : TAP imx6.sdma does not have IDCODE Info : JTAG tap: imx6.sjc tap/device found: 0x2191e01d (mfg: 0x00e, part: 0x191e, ver: 0x2) Info : imx6.cpu.0: hardware has 6 breakpoints, 4 watchpoints Info : number of cache level 1 Info : imx6.cpu.0 cluster 0 core 0 multi core</p>
]]></content:encoded>
    </item>
    <item>
      <title>Vivante MMU v1</title>
      <link>https://christian-gmeiner.info/2014-05-03-vivante-mmu-v1/</link>
      <pubDate>Sat, 03 May 2014 20:25:35 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2014-05-03-vivante-mmu-v1/</guid>
      <description>&lt;p&gt;I did spend quite some time the last days to figure out how the MMU v1 could work and what all the code in the v4 Kernel sources does. It took quite some time and a little hint from Russel to finally understand it. So lets start with the technical details.&lt;/p&gt;
&lt;p&gt;The MMU uses a page table with a maximum size of 256KB. Where each Page Table Entry (PTE) is 4 byte long. The used page size is 4K and can not be changed via some registers etc.
Lets have a look at the bit layout of a PTE.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I did spend quite some time the last days to figure out how the MMU v1 could work and what all the code in the v4 Kernel sources does. It took quite some time and a little hint from Russel to finally understand it. So lets start with the technical details.</p>
<p>The MMU uses a page table with a maximum size of 256KB. Where each Page Table Entry (PTE) is 4 byte long. The used page size is 4K and can not be changed via some registers etc.
Lets have a look at the bit layout of a PTE.</p>
<p><a href="/wp-content/uploads/2014/05/vivante_mmuv1.png"><img alt="vivante_mmuv1" loading="lazy" src="/wp-content/uploads/2014/05/vivante_mmuv1-1024x86.png"></a>
What does all that code in the v4 driver? In the end it turned out to be a ‘simple’ memory manager. All the code is needed to keep track of which pages are mapped into the GPU address area. Index 0 of the big page table array maps directly to GPU address 0x80000000 and index 1 maps directly to 0x80001000. We can quite easily map Linux kernel pages into the address range of the GPU.</p>
<p>The solution I am working on will use drm_mm as memory manager and the iommu framework to keep the page table in sync.</p>
]]></content:encoded>
    </item>
    <item>
      <title>QtCreator: ptrace operation not permitted</title>
      <link>https://christian-gmeiner.info/2014-03-17-qtcreator-ptrace-operation-not-permitted/</link>
      <pubDate>Mon, 17 Mar 2014 12:57:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2014-03-17-qtcreator-ptrace-operation-not-permitted/</guid>
      <description>&lt;p&gt;Today I wanted to debug a Qt based application within QtCreator but failed. After a quick google I found the solution:&lt;/p&gt;
&lt;div class=&#34;oembed-gist&#34;&gt;&lt;script src=&#34;https://gist.github.com/austriancoder/c2733a5ca5cfa9c23fe99c27811813d3.js&#34;&gt;&lt;/script&gt;&lt;noscript&gt;View the code on [Gist](https://gist.github.com/austriancoder/c2733a5ca5cfa9c23fe99c27811813d3).&lt;/noscript&gt;&lt;/div&gt;</description>
      <content:encoded><![CDATA[<p>Today I wanted to debug a Qt based application within QtCreator but failed. After a quick google I found the solution:</p>
<div class="oembed-gist"><script src="https://gist.github.com/austriancoder/c2733a5ca5cfa9c23fe99c27811813d3.js"></script><noscript>View the code on [Gist](https://gist.github.com/austriancoder/c2733a5ca5cfa9c23fe99c27811813d3).</noscript></div>
]]></content:encoded>
    </item>
    <item>
      <title>The next steps for etnaviv</title>
      <link>https://christian-gmeiner.info/2014-02-22-the-next-steps-for-etnaviv/</link>
      <pubDate>Sat, 22 Feb 2014 17:54:17 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2014-02-22-the-next-steps-for-etnaviv/</guid>
      <description>&lt;p&gt;I did spend some time to find the cause for the rendering issues during running some egls2 demos. The fix is a simple one-liner and I would say that GC8xx and GC2000 are ‘equal’ now. That means general work on etnaviv can start now. Currently I am looking in different problem zones and where to start.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Update mesa fork&lt;/li&gt;
&lt;li&gt;Start working on an improved compiler&lt;/li&gt;
&lt;li&gt;Start working on an kernel interface&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I think that Rob will start soon on the kernel interface and the mesa update should be doable during some hours. So I think the next big and important step is to improve the compiler. What should I say… I have basic compiler understanding, did wrote a compiler and VM during my study… thats it. I have never written a single line of glsl and I do not completely understand the Vivante GPU. So a perfect starting point for doing some hacking 🙂 The success rate will be quite low and I hope to not lose my motivation too soon.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I did spend some time to find the cause for the rendering issues during running some egls2 demos. The fix is a simple one-liner and I would say that GC8xx and GC2000 are ‘equal’ now. That means general work on etnaviv can start now. Currently I am looking in different problem zones and where to start.</p>
<ol>
<li>Update mesa fork</li>
<li>Start working on an improved compiler</li>
<li>Start working on an kernel interface</li>
</ol>
<p>I think that Rob will start soon on the kernel interface and the mesa update should be doable during some hours. So I think the next big and important step is to improve the compiler. What should I say… I have basic compiler understanding, did wrote a compiler and VM during my study… thats it. I have never written a single line of glsl and I do not completely understand the Vivante GPU. So a perfect starting point for doing some hacking 🙂 The success rate will be quite low and I hope to not lose my motivation too soon.</p>
]]></content:encoded>
    </item>
    <item>
      <title>GitHub: How to download a change as patch</title>
      <link>https://christian-gmeiner.info/2014-02-20-github-how-to-download-a-change-as-patch/</link>
      <pubDate>Thu, 20 Feb 2014 08:15:19 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2014-02-20-github-how-to-download-a-change-as-patch/</guid>
      <description>&lt;p&gt;Sometimes I can be useful to download a changes contained in a Github pull request as a unified diff. It turns out to be very easy.  To view a commit as a diff/patch file, just add &lt;code&gt;.diff&lt;/code&gt; or &lt;code&gt;.patch&lt;/code&gt; to the end of the URL&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/austriancoder/etna_viv/commit/568d290514b6e61428bb73281ac596b0404c8f70.patch&#34;&gt;For instance&lt;/a&gt; &lt;a href=&#34;https://github.com/austriancoder/etna_viv/commit/568d290514b6e61428bb73281ac596b0404c8f70.patch&#34;&gt;
&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Sometimes I can be useful to download a changes contained in a Github pull request as a unified diff. It turns out to be very easy.  To view a commit as a diff/patch file, just add <code>.diff</code> or <code>.patch</code> to the end of the URL</p>
<p><a href="https://github.com/austriancoder/etna_viv/commit/568d290514b6e61428bb73281ac596b0404c8f70.patch">For instance</a> <a href="https://github.com/austriancoder/etna_viv/commit/568d290514b6e61428bb73281ac596b0404c8f70.patch">
</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Mesa meets GC2000</title>
      <link>https://christian-gmeiner.info/2014-02-15-mesa-meets-gc2000/</link>
      <pubDate>Sat, 15 Feb 2014 20:18:25 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2014-02-15-mesa-meets-gc2000/</guid>
      <description>&lt;p&gt;Here is the first result of running &lt;a href=&#34;https://github.com/laanwj/mesatest_gles&#34;&gt;mesatest_gles &lt;/a&gt;on &lt;a href=&#34;https://github.com/austriancoder/mesa&#34;&gt;mesa&amp;amp;etna&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Following tests are showing good visual results compared to swrast:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hello_Triangle/CH02_HelloTriangle&lt;/li&gt;
&lt;li&gt;Simple_VertexShader/CH08_SimpleVertexShader&lt;/li&gt;
&lt;li&gt;CubeVBO/cube_vbo&lt;/li&gt;
&lt;li&gt;ParticleSystem/CH13_ParticleSystem&lt;/li&gt;
&lt;li&gt;Viewports/viewports&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All other are visual corrupted or segfault. So there is still some work done to get all demos
up and running.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Here is the first result of running <a href="https://github.com/laanwj/mesatest_gles">mesatest_gles </a>on <a href="https://github.com/austriancoder/mesa">mesa&amp;etna</a>:</p>
<p>Following tests are showing good visual results compared to swrast:</p>
<ul>
<li>Hello_Triangle/CH02_HelloTriangle</li>
<li>Simple_VertexShader/CH08_SimpleVertexShader</li>
<li>CubeVBO/cube_vbo</li>
<li>ParticleSystem/CH13_ParticleSystem</li>
<li>Viewports/viewports</li>
</ul>
<p>All other are visual corrupted or segfault. So there is still some work done to get all demos
up and running.</p>
]]></content:encoded>
    </item>
    <item>
      <title>GC2000 support for etnaviv</title>
      <link>https://christian-gmeiner.info/2014-02-09-gc2000-support-for-etnaviv/</link>
      <pubDate>Sun, 09 Feb 2014 17:22:56 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2014-02-09-gc2000-support-for-etnaviv/</guid>
      <description>&lt;p&gt;Today I hit an important milestone for etnaviv – an open source user-space driver for the Vivante GCxxx series of embedded GPUs.
I finally got GC2000 support to a level that it seems to work. It took me some months to get there.
At the beginning it sounds easy to rebuild a ‘driver’ if you get readable command buffer dumps. I did start with working on a simple replay program to render a cube in the same was as the binary blob does it.
But what should I say… it is quite boring to do everything by hand and not taking advantage of libetnaviv
and the ‘driver’ at all. So I decided to go the hard way and try to fix/add all missing bits until it renders something.
The good thing is that I have now some knowledge about the structure of libetnaviv, the
dirver and mesa in general. It helps a lot if you know why stuff is done that way.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Today I hit an important milestone for etnaviv – an open source user-space driver for the Vivante GCxxx series of embedded GPUs.
I finally got GC2000 support to a level that it seems to work. It took me some months to get there.
At the beginning it sounds easy to rebuild a ‘driver’ if you get readable command buffer dumps. I did start with working on a simple replay program to render a cube in the same was as the binary blob does it.
But what should I say… it is quite boring to do everything by hand and not taking advantage of libetnaviv
and the ‘driver’ at all. So I decided to go the hard way and try to fix/add all missing bits until it renders something.
The good thing is that I have now some knowledge about the structure of libetnaviv, the
dirver and mesa in general. It helps a lot if you know why stuff is done that way.</p>
<p>Also this is my first reverse engineering project I contributed to and even I have never done any graphics related stuff – okay I did
some OpenGL stuff during my studies.</p>
<p>I try to find some more time to help to create a fully open source graphics stack for Vivante GPUs.</p>
<p>If have not seen it yet: Here is a short video showing the current state of etnaviv on a iMX6q (Sabre Lite).
<a href="https://plus.google.com/102045773664179486664/posts/aiBDNmMQRTU">Video in Google+ post</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Rebase Github fork</title>
      <link>https://christian-gmeiner.info/2014-02-08-rebase-github-fork/</link>
      <pubDate>Sat, 08 Feb 2014 09:37:49 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2014-02-08-rebase-github-fork/</guid>
      <description>&lt;p&gt;Today I needed to rebase my etnaviv fork to the current master of upstream. I need to say that
I never did this before but with git this is a breeze.&lt;/p&gt;
&lt;div class=&#34;oembed-gist&#34;&gt;&lt;script src=&#34;https://gist.github.com/austriancoder/724a0a8d1db4f229e197d501f8b49fa5.js&#34;&gt;&lt;/script&gt;&lt;noscript&gt;View the code on [Gist](https://gist.github.com/austriancoder/724a0a8d1db4f229e197d501f8b49fa5).&lt;/noscript&gt;&lt;/div&gt;If you get a merge conflict during rebase, you only need to follow the instructions git gives you.</description>
      <content:encoded><![CDATA[<p>Today I needed to rebase my etnaviv fork to the current master of upstream. I need to say that
I never did this before but with git this is a breeze.</p>
<div class="oembed-gist"><script src="https://gist.github.com/austriancoder/724a0a8d1db4f229e197d501f8b49fa5.js"></script><noscript>View the code on [Gist](https://gist.github.com/austriancoder/724a0a8d1db4f229e197d501f8b49fa5).</noscript></div>If you get a merge conflict during rebase, you only need to follow the instructions git gives you.
]]></content:encoded>
    </item>
    <item>
      <title>CMake: Post install scripts for debian</title>
      <link>https://christian-gmeiner.info/2014-01-23-cmake-post-install-scripts-for-debian/</link>
      <pubDate>Thu, 23 Jan 2014 07:49:09 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2014-01-23-cmake-post-install-scripts-for-debian/</guid>
      <description>&lt;p&gt;I am using cmake during my job to create Debian installation packages for different kind of software projects. Today I run into an issue. I needed to run some post installation steps. I know that this is quite easy possible within a deb file, but how to archive the same with cmake?&lt;/p&gt;
&lt;p&gt;It turned out to be quite easy:&lt;/p&gt;
&lt;div class=&#34;oembed-gist&#34;&gt;&lt;script src=&#34;https://gist.github.com/austriancoder/1c3ba1d383fefbf8dd7fe773cebd882d.js&#34;&gt;&lt;/script&gt;&lt;noscript&gt;View the code on [Gist](https://gist.github.com/austriancoder/1c3ba1d383fefbf8dd7fe773cebd882d).&lt;/noscript&gt;&lt;/div&gt;Where postinst is the script which gets executed after the deb got installed.</description>
      <content:encoded><![CDATA[<p>I am using cmake during my job to create Debian installation packages for different kind of software projects. Today I run into an issue. I needed to run some post installation steps. I know that this is quite easy possible within a deb file, but how to archive the same with cmake?</p>
<p>It turned out to be quite easy:</p>
<div class="oembed-gist"><script src="https://gist.github.com/austriancoder/1c3ba1d383fefbf8dd7fe773cebd882d.js"></script><noscript>View the code on [Gist](https://gist.github.com/austriancoder/1c3ba1d383fefbf8dd7fe773cebd882d).</noscript></div>Where postinst is the script which gets executed after the deb got installed.
]]></content:encoded>
    </item>
    <item>
      <title>Decrypt shell commands</title>
      <link>https://christian-gmeiner.info/2013-09-05-decrypt-shell-commands/</link>
      <pubDate>Thu, 05 Sep 2013 06:27:03 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-09-05-decrypt-shell-commands/</guid>
      <description>&lt;p&gt;You may know this situation: You have seen a shell command, looked in the man page but you are no really sure what it does?&lt;/p&gt;
&lt;p&gt;It solution to this problem is quite easy: &lt;a href=&#34;http://explainshell.com/&#34; title=&#34;http://explainshell.com/&#34;&gt;http://explainshell.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://christian-gmeiner.info/wp-content/uploads/2013/09/explainshell1.png&#34;&gt;&lt;img alt=&#34;explainshell&#34; loading=&#34;lazy&#34; src=&#34;https://christian-gmeiner.info/wp-content/uploads/2013/09/explainshell1-1024x721.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The best thing is that the source code is released under GPL and can be found at &lt;a href=&#34;https://github.com/idank/explainshell&#34;&gt;GitHub&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>You may know this situation: You have seen a shell command, looked in the man page but you are no really sure what it does?</p>
<p>It solution to this problem is quite easy: <a href="http://explainshell.com/" title="http://explainshell.com/">http://explainshell.com/</a></p>
<p><a href="/wp-content/uploads/2013/09/explainshell1.png"><img alt="explainshell" loading="lazy" src="/wp-content/uploads/2013/09/explainshell1-1024x721.png"></a></p>
<p>The best thing is that the source code is released under GPL and can be found at <a href="https://github.com/idank/explainshell">GitHub</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Recreate ssh host keys in Debian</title>
      <link>https://christian-gmeiner.info/2013-08-22-recreate-ssh-host-keys-in-debian/</link>
      <pubDate>Thu, 22 Aug 2013 07:13:45 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-08-22-recreate-ssh-host-keys-in-debian/</guid>
      <description>&lt;p&gt;Sometimes it is needed to recreate the used ssh host keys and this can be done quite easy on a Debian based system.&lt;/p&gt;
&lt;div class=&#34;oembed-gist&#34;&gt;&lt;script src=&#34;https://gist.github.com/austriancoder/65c4f0141bdea7f565c1aed21404fd19.js&#34;&gt;&lt;/script&gt;&lt;noscript&gt;View the code on [Gist](https://gist.github.com/austriancoder/65c4f0141bdea7f565c1aed21404fd19).&lt;/noscript&gt;&lt;/div&gt;</description>
      <content:encoded><![CDATA[<p>Sometimes it is needed to recreate the used ssh host keys and this can be done quite easy on a Debian based system.</p>
<div class="oembed-gist"><script src="https://gist.github.com/austriancoder/65c4f0141bdea7f565c1aed21404fd19.js"></script><noscript>View the code on [Gist](https://gist.github.com/austriancoder/65c4f0141bdea7f565c1aed21404fd19).</noscript></div>
]]></content:encoded>
    </item>
    <item>
      <title>Update KDE in Ubuntu</title>
      <link>https://christian-gmeiner.info/2013-08-21-update-kde-in-ubuntu/</link>
      <pubDate>Wed, 21 Aug 2013 07:27:45 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-08-21-update-kde-in-ubuntu/</guid>
      <description>&lt;p&gt;On my work linux machine I am using Ubuntu with KDE. As the new 4.11 was released I thought it would be a good idea to update my current KDE installation. As a long-term Gentoo user it needed some more steps.&lt;/p&gt;
&lt;p&gt;sudo add-apt-repository ppa:kubuntu-ppa/backports sudo apt-get update sudo apt-get dist-upgrade&lt;/p&gt;
&lt;p&gt;I think it is really time to replace my Ubuntu installation with something different/better.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>On my work linux machine I am using Ubuntu with KDE. As the new 4.11 was released I thought it would be a good idea to update my current KDE installation. As a long-term Gentoo user it needed some more steps.</p>
<p>sudo add-apt-repository ppa:kubuntu-ppa/backports sudo apt-get update sudo apt-get dist-upgrade</p>
<p>I think it is really time to replace my Ubuntu installation with something different/better.</p>
]]></content:encoded>
    </item>
    <item>
      <title>i.MX6 - DDR3 setup</title>
      <link>https://christian-gmeiner.info/2013-07-26-i-mx6-ddr3-setup/</link>
      <pubDate>Fri, 26 Jul 2013 15:15:04 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-07-26-i-mx6-ddr3-setup/</guid>
      <description>&lt;p&gt;The company I work for has designed a custom i.MX6 based board and I am the guy who
does the board bring-up. For me the i.MX6 platform is a very good choice as support
for the hardware in u-boot and the linux kernel is quite good. So it should not be
too hard to get linux running on our custom board.&lt;/p&gt;
&lt;p&gt;But wait… as I learned from my coreboot activities – memory setup is the hardest
and most importest part. The custom board has 1GB of DDR3 on it and I started to look
how u-boot does the DDR setup. And there I read the term DCD – Device Configuration Data.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>The company I work for has designed a custom i.MX6 based board and I am the guy who
does the board bring-up. For me the i.MX6 platform is a very good choice as support
for the hardware in u-boot and the linux kernel is quite good. So it should not be
too hard to get linux running on our custom board.</p>
<p>But wait… as I learned from my coreboot activities – memory setup is the hardest
and most importest part. The custom board has 1GB of DDR3 on it and I started to look
how u-boot does the DDR setup. And there I read the term DCD – Device Configuration Data.</p>
<p>DCD does contain the init sequence for DDR3 and I had to look up some stuff in the
“<a href="http://cache.freescale.com/files/32bit/doc/ref_manual/IMX6DQRM.pdf" title="i.MX 6Dual/6Quad Applications Processor Reference Manual">i.MX 6Dual/6Quad Applications Processor Reference Manual</a>” to find out that this must
be some kind of black magic. I tried my luck with the DDR3 Stress Tester from Freescale
and failed. It was so hard to get all those register correct if you do not know much about
DDR3 at all.</p>
<p>Luckily I got a hint that in the Freescale commuity is something which could help me – thanks Fabio. It turns out to be an Excel sheet where I filled in few values and got a DDR3 init script for the DDR3 Stress Tester.</p>
<p>10 Minutes after I got the Excel sheet into my hands it looks like I got the memory up
and running – nice!</p>
<p>The “magic” Excel sheet can be found <a href="https://community.freescale.com/docs/DOC-94917" title="i.Mx6DQSDL DDR3 Script Aid">here.</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Rebuild a Debian package from source</title>
      <link>https://christian-gmeiner.info/2013-06-12-rebuild-a-debian-package-from-source/</link>
      <pubDate>Wed, 12 Jun 2013 10:49:25 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-06-12-rebuild-a-debian-package-from-source/</guid>
      <description>&lt;p&gt;In some rare cases I need to debug some networking protocols and my target of interest
is NTP. I am debugging an issue where (maybe) NTP sets the current time backwards about
two hours. My first candidate to look deeper is ntpd.&lt;/p&gt;
&lt;p&gt;But what do I see… debugging option is disabled in the Debian squeeze package of ntp.
WTF?! – the only nice way to do useful debugging without wireshark. The good thing is
that Ubuntu had the same miss-configuration and got it &lt;a href=&#34;https://bugs.launchpad.net/ubuntu/+source/ntp/+bug/47683&#34;&gt;fixed&lt;/a&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In some rare cases I need to debug some networking protocols and my target of interest
is NTP. I am debugging an issue where (maybe) NTP sets the current time backwards about
two hours. My first candidate to look deeper is ntpd.</p>
<p>But what do I see… debugging option is disabled in the Debian squeeze package of ntp.
WTF?! – the only nice way to do useful debugging without wireshark. The good thing is
that Ubuntu had the same miss-configuration and got it <a href="https://bugs.launchpad.net/ubuntu/+source/ntp/+bug/47683">fixed</a>.</p>
<p>So I only need to rebuild the ntpd package with debugging enabled.</p>
<h1 id="sudo-apt-get-build-dep-ntpd">sudo apt-get build-dep ntpd</h1>
<h1 id="sudo-apt-get-source-ntpd">sudo apt-get source ntpd</h1>
<h1 id="cd-ntp-426p2dfsg">cd ntp-4.2.6.p2+dfsg</h1>
<h1 id="nano-debianrules">nano debian/rules</h1>
<h1 id="dpkg-buildpackage--rfakeroot--uc--b">dpkg-buildpackage -rfakeroot -uc -b</h1>
<p>The result is a deb in the parent folder.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Building etna_viv on the sabre lite</title>
      <link>https://christian-gmeiner.info/2013-04-29-building-etna_viv-on-the-sabre-lite/</link>
      <pubDate>Mon, 29 Apr 2013 19:03:10 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-04-29-building-etna_viv-on-the-sabre-lite/</guid>
      <description>&lt;p&gt;At the moment I am playing around with a cute nice little imx6q board – &lt;a href=&#34;http://boundarydevices.com/products/sabre-lite-imx6-sbc/&#34;&gt;the sabre lite&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I am running a freescale based RFS with the binary libGAL.so blob in the user space. So why
not look into etna_viv and get it compiled. It turns out to be as simple as this.&lt;/p&gt;
&lt;p&gt;git clone git://github.com/laanwj/etna_viv.git cd etna_viv/native export GCABI=imx6 export CFLAGS=&amp;quot;-D_POSIX_C_SOURCE=200809 -D_GNU_SOURCE -DLINUX -pthread&amp;quot; export CXXFLAGS=&amp;quot;-D_POSIX_C_SOURCE=200809 -D_GNU_SOURCE -DLINUX -pthread&amp;quot; make&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>At the moment I am playing around with a cute nice little imx6q board – <a href="http://boundarydevices.com/products/sabre-lite-imx6-sbc/">the sabre lite</a>.</p>
<p>I am running a freescale based RFS with the binary libGAL.so blob in the user space. So why
not look into etna_viv and get it compiled. It turns out to be as simple as this.</p>
<p>git clone git://github.com/laanwj/etna_viv.git cd etna_viv/native export GCABI=imx6 export CFLAGS=&quot;-D_POSIX_C_SOURCE=200809 -D_GNU_SOURCE -DLINUX -pthread&quot; export CXXFLAGS=&quot;-D_POSIX_C_SOURCE=200809 -D_GNU_SOURCE -DLINUX -pthread&quot; make</p>
<p>At the moment the GC2000 support is non existent but it should be possible to add support
for it in the foreseeable future. To get a picture what needs to be done have a lookt at
<a href="https://blog.visucore.com/2013/3/3/gc2000-vs-gc800">https://blog.visucore.com/2013/3/3/gc2000-vs-gc800</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>JQuery: autoscroll to last line of a div</title>
      <link>https://christian-gmeiner.info/2013-03-16-jquery-autoscroll-to-last-line-of-a-div/</link>
      <pubDate>Sat, 16 Mar 2013 17:18:58 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-03-16-jquery-autoscroll-to-last-line-of-a-div/</guid>
      <description>&lt;p&gt;Image you are working on a small web application where you use a JQuery UI dialog
to inform the user about the current process.&lt;/p&gt;
 &lt;ul id=&#34;progress&#34; style=&#34;width: 300px; height: 200px; overflow: auto&#34;&gt; &lt;/ul&gt;
&lt;p&gt;Triggered via SSE I am appending some messages via JavaScript.&lt;/p&gt;
&lt;p&gt;$(&amp;rsquo;#progress&amp;rsquo;).append(&amp;quot;&amp;lt;span class=&amp;lsquo;ui-icon ui-icon-alert&amp;rsquo; style=&amp;lsquo;float: left; margin-right: .3em&amp;rsquo;;&amp;gt;&lt;/span&gt;&amp;quot; + stderr + &amp;ldquo;&lt;br&gt;&amp;rdquo;);&lt;/p&gt;
&lt;p&gt;In order to automaticly scroll to the last line I am using this two magic lines of JavaScript:&lt;/p&gt;
&lt;p&gt;var height = $(&amp;rsquo;#progress&amp;rsquo;)[0].scrollHeight; $(&amp;rsquo;#progress&amp;rsquo;).scrollTop(height);&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Image you are working on a small web application where you use a JQuery UI dialog
to inform the user about the current process.</p>
 <ul id="progress" style="width: 300px; height: 200px; overflow: auto"> </ul>
<p>Triggered via SSE I am appending some messages via JavaScript.</p>
<p>$(&rsquo;#progress&rsquo;).append(&quot;&lt;span class=&lsquo;ui-icon ui-icon-alert&rsquo; style=&lsquo;float: left; margin-right: .3em&rsquo;;&gt;</span>&quot; + stderr + &ldquo;<br>&rdquo;);</p>
<p>In order to automaticly scroll to the last line I am using this two magic lines of JavaScript:</p>
<p>var height = $(&rsquo;#progress&rsquo;)[0].scrollHeight; $(&rsquo;#progress&rsquo;).scrollTop(height);</p>
<p>It is simple as that.</p>
]]></content:encoded>
    </item>
    <item>
      <title>git: RPC failed; result=22, HTTP code = 504</title>
      <link>https://christian-gmeiner.info/2013-03-07-git-rpc-failed/</link>
      <pubDate>Thu, 07 Mar 2013 15:44:38 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-03-07-git-rpc-failed/</guid>
      <description>&lt;p&gt;git clone &lt;a href=&#34;http://review.coreboot.org/p/coreboot.git&#34;&gt;http://review.coreboot.org/p/coreboot.git&lt;/a&gt; coreboot Cloning into &amp;lsquo;coreboot&amp;rsquo;&amp;hellip; error: RPC failed; result=22, HTTP code = 504 fatal: The remote end hung up unexpectedly&lt;/p&gt;
&lt;p&gt;The error occurs in ‘libcurl’, which is the underlying protocol for http. To get more details about the error, set GIT_CURL_VERBOSE=1&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>git clone <a href="http://review.coreboot.org/p/coreboot.git">http://review.coreboot.org/p/coreboot.git</a> coreboot Cloning into &lsquo;coreboot&rsquo;&hellip; error: RPC failed; result=22, HTTP code = 504 fatal: The remote end hung up unexpectedly</p>
<p>The error occurs in ‘libcurl’, which is the underlying protocol for http. To get more details about the error, set GIT_CURL_VERBOSE=1</p>
]]></content:encoded>
    </item>
    <item>
      <title>SMBus Compatibility With an I²C Device</title>
      <link>https://christian-gmeiner.info/2013-02-23-smbus-compatibility-with-an-i-c2-b2c-device/</link>
      <pubDate>Sat, 23 Feb 2013 10:54:30 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-02-23-smbus-compatibility-with-an-i-c2-b2c-device/</guid>
      <description>&lt;p&gt;Some naive guys – like me – think that SMBus and I²C are equal expect the bus level. But in the last days I run into a problem where an at24 based EEPROM connected via SMBus triggers a bus collision after a warm reboot. After some hours of debugging – even staring minutes at a oscilloscope showing SDD and SDC lines – I started to add some dump_stack() calls into i2c_core.c file form a recent linux kernel. And I found the bad bus transaction – i2c_probe_func_quick_read(..).&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Some naive guys – like me – think that SMBus and I²C are equal expect the bus level. But in the last days I run into a problem where an at24 based EEPROM connected via SMBus triggers a bus collision after a warm reboot. After some hours of debugging – even staring minutes at a oscilloscope showing SDD and SDC lines – I started to add some dump_stack() calls into i2c_core.c file form a recent linux kernel. And I found the bad bus transaction – i2c_probe_func_quick_read(..).</p>
<p>But whats exactly the problem here?</p>
<blockquote>
<p>The SMBus specification describes a number of standardized
transactions. Each chip on the bus can support each given transaction
type or not. In practice, each slave chip only supports a subset of the
SMBus specification. The Linux i2c subsystem abuses this
transaction type for device detection purposes, because it is known to
give good results in practice, but ideally it shouldn’t do that.</p>
<p>There have been some devices known to lock up the SMBus on Quick
command with data bit = 1. In most cases
these were write-only devices, which didn’t expect a transaction
starting like a read (the SMBus specification says that a Quick command
with data bit = 1 is writing 1 bit to the slave, but the I2C
specification says this is a <em>read</em> transaction of length 0.)</p>
<p>This SMBus Quick command thing keeps causing trouble and confusing
people. Not much we can do though. If your slaves don’t like the quick
command, just don’t send that command to them.</p>
<p><a href="http://www.mail-archive.com/linux-i2c@vger.kernel.org/msg00209.html" title="SMBus quick command problem">SMBus quick command problem</a></p>
</blockquote>
<p>The solution is quite simple: use i2c_new_probed_device(..) function for probing devices on the SMBus/I²C-Bus. By the way I have found a nice comparison from TI: <a href="http://www.ti.com/lit/an/sloa132/sloa132.pdf">SMBus vs. I²C</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Sending patches from a local git repository</title>
      <link>https://christian-gmeiner.info/2013-02-15-sending-patches-from-a-local-git-repository/</link>
      <pubDate>Fri, 15 Feb 2013 15:40:49 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-02-15-sending-patches-from-a-local-git-repository/</guid>
      <description>&lt;p&gt;At the moment I am reworking some old seabios patches as I want them in upstream. At the moment my git log shows this:&lt;/p&gt;
&lt;p&gt;commit fd7e6128d5fb9b8297a4a20f3288c130a554147b Author: Christian Gmeiner &lt;a href=&#34;mailto:christian.gmeiner@gmail.com&#34;&gt;christian.gmeiner@gmail.com&lt;/a&gt; Date: Thu Feb 14 10:24:59 2013 +0100 geodevga: fix wrong define name Signed-off-by: Christian Gmeiner &lt;a href=&#34;mailto:christian.gmeiner@gmail.com&#34;&gt;christian.gmeiner@gmail.com&lt;/a&gt; commit b1268e8100f0bcf0655b65326856e6f33e3625c1 Author: Christian Gmeiner &lt;a href=&#34;mailto:christian.gmeiner@gmail.com&#34;&gt;christian.gmeiner@gmail.com&lt;/a&gt; Date: Thu Feb 14 10:22:58 2013 +0100 geodevga: add debug to msr functions Signed-off-by: Christian Gmeiner &lt;a href=&#34;mailto:christian.gmeiner@gmail.com&#34;&gt;christian.gmeiner@gmail.com&lt;/a&gt; commit dde4df84126a460c454ca79fc8dc5b0ae4aa876e Author: Christian Gmeiner &lt;a href=&#34;mailto:christian.gmeiner@gmail.com&#34;&gt;christian.gmeiner@gmail.com&lt;/a&gt; Date: Thu Feb 14 10:19:05 2013 +0100 geodevga: move output setup to own function Signed-off-by: Christian Gmeiner &lt;a href=&#34;mailto:christian.gmeiner@gmail.com&#34;&gt;christian.gmeiner@gmail.com&lt;/a&gt; commit bba85a38c67aa2b52f146b5cefe58b00f516fc2e Author: Christian Gmeiner &lt;a href=&#34;mailto:christian.gmeiner@gmail.com&#34;&gt;christian.gmeiner@gmail.com&lt;/a&gt; Date: Thu Feb 14 10:13:59 2013 +0100 geodevga: move framebuffer setup Framebuffer setup has nothing to do with dc_setup(..) so move it to geodevga_init(..). Signed-off-by: Christian Gmeiner &lt;a href=&#34;mailto:christian.gmeiner@gmail.com&#34;&gt;christian.gmeiner@gmail.com&lt;/a&gt; commit 0b3dee01385e65f2b88600c9b663589343ac4abe Author: Christian Gmeiner &lt;a href=&#34;mailto:christian.gmeiner@gmail.com&#34;&gt;christian.gmeiner@gmail.com&lt;/a&gt; Date: Thu Feb 14 10:05:45 2013 +0100 geodevga: fix errors in geode_fp_* functions Signed-off-by: Christian Gmeiner &lt;a href=&#34;mailto:christian.gmeiner@gmail.com&#34;&gt;christian.gmeiner@gmail.com&lt;/a&gt; commit 4b1d2be6e1c73d1fc9a984ca7fe6c14d433171cc Author: David Woodhouse &lt;a href=&#34;mailto:David.Woodhouse@intel.com&#34;&gt;David.Woodhouse@intel.com&lt;/a&gt; Date: Sun Feb 10 00:51:56 2013 +0000 Unify return path for CSM to go via csm_return() This allows us to keep the entry_csm code simple, and ensures that we consistently do things like saving the PIC mask (and later setting UmbStart) on the way back to UEFI. &amp;hellip;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>At the moment I am reworking some old seabios patches as I want them in upstream. At the moment my git log shows this:</p>
<p>commit fd7e6128d5fb9b8297a4a20f3288c130a554147b Author: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> Date: Thu Feb 14 10:24:59 2013 +0100 geodevga: fix wrong define name Signed-off-by: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> commit b1268e8100f0bcf0655b65326856e6f33e3625c1 Author: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> Date: Thu Feb 14 10:22:58 2013 +0100 geodevga: add debug to msr functions Signed-off-by: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> commit dde4df84126a460c454ca79fc8dc5b0ae4aa876e Author: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> Date: Thu Feb 14 10:19:05 2013 +0100 geodevga: move output setup to own function Signed-off-by: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> commit bba85a38c67aa2b52f146b5cefe58b00f516fc2e Author: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> Date: Thu Feb 14 10:13:59 2013 +0100 geodevga: move framebuffer setup Framebuffer setup has nothing to do with dc_setup(..) so move it to geodevga_init(..). Signed-off-by: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> commit 0b3dee01385e65f2b88600c9b663589343ac4abe Author: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> Date: Thu Feb 14 10:05:45 2013 +0100 geodevga: fix errors in geode_fp_* functions Signed-off-by: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> commit 4b1d2be6e1c73d1fc9a984ca7fe6c14d433171cc Author: David Woodhouse <a href="mailto:David.Woodhouse@intel.com">David.Woodhouse@intel.com</a> Date: Sun Feb 10 00:51:56 2013 +0000 Unify return path for CSM to go via csm_return() This allows us to keep the entry_csm code simple, and ensures that we consistently do things like saving the PIC mask (and later setting UmbStart) on the way back to UEFI. &hellip;</p>
<p>The first step is to generate the patches.</p>
<p>$ git format-patch -M origin/master 0001-geodevga-fix-errors-in-geode_fp_-functions.patch 0002-geodevga-move-framebuffer-setup.patch 0003-geodevga-move-output-setup-to-own-function.patch 0004-geodevga-add-debug-to-msr-functions.patch 0005-geodevga-fix-wrong-define-name.patch</p>
<p>Now we simply need to send them via mail – git helps here too 🙂</p>
<p>$ git send-email <em>.patch 0001-geodevga-fix-errors-in-geode_fp_-functions.patch 0001-geodevga-fix-wrong-define-name.patch 0002-geodevga-move-framebuffer-setup.patch 0003-geodevga-move-output-setup-to-own-function.patch 0004-geodevga-add-debug-to-msr-functions.patch 0005-geodevga-fix-wrong-define-name.patch Who should the emails appear to be from? [Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a>] Emails will be sent from: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> Who should the emails be sent to (if any)? <a href="mailto:seabios@seabios.org">seabios@seabios.org</a> Message-ID to be used as In-Reply-To for the first email (if any)? (mbox) Adding cc: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> from line &lsquo;From: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a>&rsquo; (body) Adding cc: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> from line &lsquo;Signed-off-by: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a>&rsquo; From: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> To: <a href="mailto:seabios@seabios.org">seabios@seabios.org</a> Cc: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> Subject: [PATCH 1/5] geodevga: fix errors in geode_fp_</em> functions Date: Thu, 14 Feb 2013 10:34:32 +0100 Message-Id: <a href="mailto:1360834477-18802-1-git-send-email-christian.gmeiner@gmail.com">1360834477-18802-1-git-send-email-christian.gmeiner@gmail.com</a> X-Mailer: git-send-email 1.7.12.2.421.g261b511 The Cc list above has been expanded by additional addresses found in the patch commit message. By default send-email prompts before sending whenever this occurs. This behavior is controlled by the sendemail.confirm configuration setting. For additional information, run &lsquo;git send-email &ndash;help&rsquo;. To retain the current behavior, but squelch this message, run &lsquo;git config &ndash;global sendemail.confirm auto&rsquo;. Send this email? ([y]es|[n]o|[q]uit|[a]ll): a OK. Log says: Server: smtp.gmail.com MAIL FROM:<a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> RCPT TO:<a href="mailto:seabios@seabios.org">seabios@seabios.org</a> RCPT TO:<a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> From: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> To: <a href="mailto:seabios@seabios.org">seabios@seabios.org</a> Cc: Christian Gmeiner <a href="mailto:christian.gmeiner@gmail.com">christian.gmeiner@gmail.com</a> Subject: [PATCH 1/5] geodevga: fix errors in geode_fp_* functions Date: Thu, 14 Feb 2013 10:34:32 +0100 Message-Id: <a href="mailto:1360834477-18802-1-git-send-email-christian.gmeiner@gmail.com">1360834477-18802-1-git-send-email-christian.gmeiner@gmail.com</a> X-Mailer: git-send-email 1.7.12.2.421.g261b511 Result: 250 2.0.0 OK 1360833086 q5sm77386411eep.11 - gsmtp &hellip; &hellip;</p>
]]></content:encoded>
    </item>
    <item>
      <title>I ♥ Free Software</title>
      <link>https://christian-gmeiner.info/2013-02-14-i-love-free-software/</link>
      <pubDate>Thu, 14 Feb 2013 17:03:02 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-02-14-i-love-free-software/</guid>
      <description>&lt;p&gt;Today is February 14. Some think of it as flower grocer appreciation day, but most (and for better reasons) celebrate it as the international &lt;a href=&#34;http://fsfe.org/campaigns/ilovefs/2013/ilovefs.en.html&#34;&gt;I ♥ Free Software day&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://christian-gmeiner.info/wp-content/uploads/2013/02/valentine-2010.png&#34;&gt;&lt;img alt=&#34;valentine-2010&#34; loading=&#34;lazy&#34; src=&#34;https://christian-gmeiner.info/wp-content/uploads/2013/02/valentine-2010.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Free and open source software makes it possible to fix problems and/or implement new features in software I use. I could write a lot of text why I think it is a good idea to support the open source community but I want you to form an opinion about this topic buy simply using open source software and support it. It does not mean you need to send in some patches… it starts with simple things like bug reports or user support.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Today is February 14. Some think of it as flower grocer appreciation day, but most (and for better reasons) celebrate it as the international <a href="http://fsfe.org/campaigns/ilovefs/2013/ilovefs.en.html">I ♥ Free Software day</a>.</p>
<p><a href="/wp-content/uploads/2013/02/valentine-2010.png"><img alt="valentine-2010" loading="lazy" src="/wp-content/uploads/2013/02/valentine-2010.png"></a></p>
<p>Free and open source software makes it possible to fix problems and/or implement new features in software I use. I could write a lot of text why I think it is a good idea to support the open source community but I want you to form an opinion about this topic buy simply using open source software and support it. It does not mean you need to send in some patches… it starts with simple things like bug reports or user support.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Which colors can work together?</title>
      <link>https://christian-gmeiner.info/2013-02-12-which-colors-can-work-together/</link>
      <pubDate>Tue, 12 Feb 2013 13:07:52 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-02-12-which-colors-can-work-together/</guid>
      <description>&lt;p&gt;In some rare cases I need to find the correct colors that can ‘work’ together. As I do not call me the graphical/designer guy I always use little helpers.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://colorschemedesigner.com/&#34;&gt;http://colorschemedesigner.com&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In some rare cases I need to find the correct colors that can ‘work’ together. As I do not call me the graphical/designer guy I always use little helpers.</p>
<p><a href="http://colorschemedesigner.com/">http://colorschemedesigner.com</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>The choice of jQuery selector&#39;s</title>
      <link>https://christian-gmeiner.info/2013-02-05-the-choice-of-jquery-selectors/</link>
      <pubDate>Tue, 05 Feb 2013 14:18:19 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-02-05-the-choice-of-jquery-selectors/</guid>
      <description>&lt;p&gt;Sometimes if you are doing some fancy HTML5 development you wonder what jQuery selector
would do the job. In such a case I can recommend the following little helper 🙂&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://codylindley.com/jqueryselectors/&#34; title=&#34;Selectors&#34;&gt;http://codylindley.com/jqueryselectors/&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Sometimes if you are doing some fancy HTML5 development you wonder what jQuery selector
would do the job. In such a case I can recommend the following little helper 🙂</p>
<p><a href="http://codylindley.com/jqueryselectors/" title="Selectors">http://codylindley.com/jqueryselectors/</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Add vendor specific information&#39;s to a coreboot rom</title>
      <link>https://christian-gmeiner.info/2013-02-05-add-vendor-specific-informations-to-a-coreboot-rom/</link>
      <pubDate>Tue, 05 Feb 2013 12:54:43 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-02-05-add-vendor-specific-informations-to-a-coreboot-rom/</guid>
      <description>&lt;p&gt;Sometimes it is needed to add some vendor specific information’s like a version string
to a generated coreboot rom. For this example we assume we want the area from 0x00 to 0x30
for such kind of data.&lt;/p&gt;
&lt;p&gt;The first idea is to use cbfstool. Thanks to some guys in the IRC channel it looks like the
current build system does something like:&lt;/p&gt;
&lt;p&gt;cbfstool -o $$(( $(CONFIG_ROM_SIZE) - $(CONFIG_CBFS_SIZE) )) &amp;hellip;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Sometimes it is needed to add some vendor specific information’s like a version string
to a generated coreboot rom. For this example we assume we want the area from 0x00 to 0x30
for such kind of data.</p>
<p>The first idea is to use cbfstool. Thanks to some guys in the IRC channel it looks like the
current build system does something like:</p>
<p>cbfstool -o $$(( $(CONFIG_ROM_SIZE) - $(CONFIG_CBFS_SIZE) )) &hellip;</p>
<p>So all we need is to change CBFS_SIZE to ROM_SIZE – 0x30 in .config file.</p>
<p>&hellip; CONFIG_CONSOLE_SERIAL8250=y # CONFIG_USBDEBUG is not set # CONFIG_K8_REV_F_SUPPORT is not set CONFIG_CPU_ADDR_BITS=32 CONFIG_BOARD_ROMSIZE_KB_2048=y # CONFIG_COREBOOT_ROMSIZE_KB_64 is not set # CONFIG_COREBOOT_ROMSIZE_KB_128 is not set # CONFIG_COREBOOT_ROMSIZE_KB_256 is not set &hellip; CONFIG_CORE_GLIU_500_266=y CONFIG_PLLMSRhi=0x39c # CONFIG_NORTHBRIDGE_AMD_AGESA is not set # CONFIG_AMD_NB_CIMX is not set # CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set CONFIG_CBFS_SIZE=0x1FFFD0 # # Southbridge # CONFIG_SOUTHBRIDGE_AMD_CS5536=y &hellip;</p>
<p>This results in the wanted result:</p>
<p>&hellip; coreboot.rom: 2048 kB, bootblocksize 688, romsize 2097152, offset 0x30 alignment: 64 bytes, architecture: x86 Name Offset Type Size vsa 0x30 stage 55124 config 0xd7c0 raw 2810 (empty) 0xe300 null 7256 fallback/romstage 0xff80 stage 19339 fallback/coreboot_ram 0x14b80 stage 38852 fallback/payload 0x1e380 payload 21831 (empty) 0x23900 null 1950728</p>
<p>And here the file based prove:</p>
<h1 id="hexedit-buildcorebootrom-00000000-ff-ff-ff-ff-ff-ff-ff-ff--00000008-ff-ff-ff-ff-ff-ff-ff-ff--00000010-ff-ff-ff-ff-ff-ff-ff-ff--00000018-ff-ff-ff-ff-ff-ff-ff-ff--00000020-ff-ff-ff-ff-ff-ff-ff-ff--00000028-ff-ff-ff-ff-ff-ff-ff-ff--00000030-4c-41-52-43-48-49-56-45-larchive-00000038-00-00-d7-54-00-00-00-10-t-00000040-00-00-00-00-00-00-00-28-">hexedit build/coreboot.rom 00000000 FF FF FF FF FF FF FF FF &hellip;&hellip;.. 00000008 FF FF FF FF FF FF FF FF &hellip;&hellip;.. 00000010 FF FF FF FF FF FF FF FF &hellip;&hellip;.. 00000018 FF FF FF FF FF FF FF FF &hellip;&hellip;.. 00000020 FF FF FF FF FF FF FF FF &hellip;&hellip;.. 00000028 FF FF FF FF FF FF FF FF &hellip;&hellip;.. 00000030 4C 41 52 43 48 49 56 45 LARCHIVE 00000038 00 00 D7 54 00 00 00 10 &hellip;T&hellip;. 00000040 00 00 00 00 00 00 00 28 &hellip;&hellip;.(</h1>
]]></content:encoded>
    </item>
    <item>
      <title>Detect initramfs under Debian squeeze</title>
      <link>https://christian-gmeiner.info/2013-02-04-detect-initramfs-under-debian-squeeze/</link>
      <pubDate>Mon, 04 Feb 2013 11:11:19 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-02-04-detect-initramfs-under-debian-squeeze/</guid>
      <description>&lt;p&gt;I am looking for a way to detect If a initramfs was used during boot. And after some reboots
and reading of init script of initramfs-tools I found this solution.&lt;/p&gt;
&lt;p&gt;#!/bin/bash if [ -e /dev/.initramfs ]; then echo YES else echo NO fi&lt;/p&gt;
&lt;p&gt;This may not work under wheezy or any other working distribution. But that’s okay for now 🙂&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I am looking for a way to detect If a initramfs was used during boot. And after some reboots
and reading of init script of initramfs-tools I found this solution.</p>
<p>#!/bin/bash if [ -e /dev/.initramfs ]; then echo YES else echo NO fi</p>
<p>This may not work under wheezy or any other working distribution. But that’s okay for now 🙂</p>
]]></content:encoded>
    </item>
    <item>
      <title>systemd on a Gentoo based system</title>
      <link>https://christian-gmeiner.info/2013-01-21-systemd-on-a-gentoo-based-system/</link>
      <pubDate>Mon, 21 Jan 2013 21:03:26 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2013-01-21-systemd-on-a-gentoo-based-system/</guid>
      <description>&lt;p&gt;I always wanted to try out systemd as I like the ideas and concept behind it. So lets get started:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&#34;line-height: 15px;&#34;&gt;add systemd USE-flag&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;emerge –ask –changed-use –deep @world&lt;/li&gt;
&lt;li&gt;emerge –ask systemd&lt;/li&gt;
&lt;li&gt;change grub config to use init=/usr/bin/systemd&lt;/li&gt;
&lt;li&gt;reboot&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;localhost christian # systemd-analyze Traceback (most recent call last): File &amp;ldquo;/usr/bin/systemd-analyze&amp;rdquo;, line 23, in &lt;module&gt; from gi.repository import Gio ImportError: No module named gi.repository&lt;/p&gt;
&lt;p&gt;This can be fixed with:&lt;/p&gt;
&lt;h1 id=&#34;emerge--av-dev-pythonpygobject&#34;&gt;emerge -av dev-python/pygobject&lt;/h1&gt;
&lt;p&gt;Here are the first results:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I always wanted to try out systemd as I like the ideas and concept behind it. So lets get started:</p>
<ul>
<li><span style="line-height: 15px;">add systemd USE-flag</span></li>
<li>emerge –ask –changed-use –deep @world</li>
<li>emerge –ask systemd</li>
<li>change grub config to use init=/usr/bin/systemd</li>
<li>reboot</li>
</ul>
<p>localhost christian # systemd-analyze Traceback (most recent call last): File &ldquo;/usr/bin/systemd-analyze&rdquo;, line 23, in <module> from gi.repository import Gio ImportError: No module named gi.repository</p>
<p>This can be fixed with:</p>
<h1 id="emerge--av-dev-pythonpygobject">emerge -av dev-python/pygobject</h1>
<p>Here are the first results:</p>
<p>localhost christian # systemd-analyze Startup finished in 2352ms (kernel) + 90695ms (userspace) = 93048ms localhost christian # systemd-analyze blame 3567ms NetworkManager.service 1311ms systemd-logind.service 530ms tmp.mount 528ms systemd-udevd.service 519ms systemd-vconsole-setup.service 393ms systemd-udev-trigger.service 363ms polkit.service 352ms sys-kernel-debug.mount 338ms dev-mqueue.mount 321ms dev-hugepages.mount 300ms boot-efi.mount 222ms systemd-sysctl.service 149ms systemd-user-sessions.service 114ms systemd-tmpfiles-setup.service 88ms console-kit-log-system-start.service 73ms console-kit-daemon.service 49ms dev-sda1.swap 44ms upower.service 33ms systemd-remount-fs.service</p>
<p>So my system boots 🙂 Lets see what is left to replace openrc.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Couldn&#39;t register serial port 0000:02:0a.2: -28</title>
      <link>https://christian-gmeiner.info/2012-10-31-couldnt-register-serial-port-0000020a-2-28/</link>
      <pubDate>Wed, 31 Oct 2012 09:10:23 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2012-10-31-couldnt-register-serial-port-0000020a-2-28/</guid>
      <description>&lt;p&gt;I run into a problem where I have a device which has two normal serial ports and some on a PCI device.
After booting the kernel I got this error line:&lt;/p&gt;
&lt;p&gt;Couldn&amp;rsquo;t register serial port 0000:02:0a.2: -28&lt;/p&gt;
&lt;p&gt;In order to get more than 2 serial ports working, I “fixed” my currently used kernel config:&lt;/p&gt;
&lt;p&gt;CONFIG_SERIAL_8250_NR_UARTS=32 CONFIG_SERIAL_8250_RUNTIME_UARTS=6&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I run into a problem where I have a device which has two normal serial ports and some on a PCI device.
After booting the kernel I got this error line:</p>
<p>Couldn&rsquo;t register serial port 0000:02:0a.2: -28</p>
<p>In order to get more than 2 serial ports working, I “fixed” my currently used kernel config:</p>
<p>CONFIG_SERIAL_8250_NR_UARTS=32 CONFIG_SERIAL_8250_RUNTIME_UARTS=6</p>
]]></content:encoded>
    </item>
    <item>
      <title>Petition to stop software patents in Europe</title>
      <link>https://christian-gmeiner.info/2012-10-22-petition-to-stop-software-patents-in-europe/</link>
      <pubDate>Mon, 22 Oct 2012 10:01:53 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2012-10-22-petition-to-stop-software-patents-in-europe/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://petition.stopsoftwarepatents.eu/521006897931/&#34;&gt;&lt;img alt=&#34;stopsoftwarepatents.eu oetition banner&#34; loading=&#34;lazy&#34; src=&#34;http://petition.stopsoftwarepatents.eu/banner/521006897931/ssp-732-121.gif&#34;&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><a href="http://petition.stopsoftwarepatents.eu/521006897931/"><img alt="stopsoftwarepatents.eu oetition banner" loading="lazy" src="http://petition.stopsoftwarepatents.eu/banner/521006897931/ssp-732-121.gif"></a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Git via Git</title>
      <link>https://christian-gmeiner.info/2012-10-15-git-via-git/</link>
      <pubDate>Mon, 15 Oct 2012 17:49:40 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2012-10-15-git-via-git/</guid>
      <description>&lt;p&gt;If you already have Git installed, you can get the latest development version via Git itself:&lt;/p&gt;
&lt;p&gt;git clone &lt;a href=&#34;https://github.com/git/git.git&#34;&gt;https://github.com/git/git.git&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>If you already have Git installed, you can get the latest development version via Git itself:</p>
<p>git clone <a href="https://github.com/git/git.git">https://github.com/git/git.git</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Change mac address under linux - the brutal way</title>
      <link>https://christian-gmeiner.info/2012-10-13-change-mac-address-under-linux-the-brutal-way/</link>
      <pubDate>Sat, 13 Oct 2012 11:42:24 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2012-10-13-change-mac-address-under-linux-the-brutal-way/</guid>
      <description>&lt;p&gt;Last days I run into a problem that I needed to change the mac address of a network card directly under linux. In the last years VxWorks was used for this purpose – oh and yes I know that you should not change a mac address 🙂 But I am working in a company which produces devices with network ports and they need an initial mac address.&lt;/p&gt;
&lt;p&gt;The first thing you would try is to use ifconfig to change the mac address.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Last days I run into a problem that I needed to change the mac address of a network card directly under linux. In the last years VxWorks was used for this purpose – oh and yes I know that you should not change a mac address 🙂 But I am working in a company which produces devices with network ports and they need an initial mac address.</p>
<p>The first thing you would try is to use ifconfig to change the mac address.</p>
<p>ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx</p>
<p>root@OT:~# strace ifconfig eth0 hw ether 00:10:7e:02:52:b6 execve(&quot;/sbin/ifconfig&quot;, [&ldquo;ifconfig&rdquo;, &ldquo;eth0&rdquo;, &ldquo;hw&rdquo;, &ldquo;ether&rdquo;, &ldquo;00:10:7e:02:52:b6&rdquo;], [/* 11 vars */]) = 0 brk(0) = 0x943b000 access(&quot;/etc/ld.so.nohwcap&quot;, F_OK) = -1 ENOENT (No such file or directory) mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77d0000 access(&quot;/etc/ld.so.preload&quot;, R_OK) = -1 ENOENT (No such file or directory) open(&quot;/etc/ld.so.cache&quot;, O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=20075, &hellip;}) = 0 mmap2(NULL, 20075, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb77cb000 close(3) = 0 access(&quot;/etc/ld.so.nohwcap&quot;, F_OK) = -1 ENOENT (No such file or directory) open(&quot;/lib/libc.so.6&quot;, O_RDONLY) = 3 read(3, &ldquo;177ELF111\0\0\0\0\0\0\0\0\03\03\01\0\0\0360m1\0004\0\0\0&rdquo;&hellip;, 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=1319176, &hellip;}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77ca000 mmap2(NULL, 1329480, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7685000 mprotect(0xb77c3000, 4096, PROT_NONE) = 0 mmap2(0xb77c4000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13e) = 0xb77c4000 mmap2(0xb77c7000, 10568, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb77c7000 close(3) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7684000 set_thread_area({entry_number:-1 -&gt; 6, base_addr:0xb76846c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 mprotect(0xb77c4000, 8192, PROT_READ) = 0 mprotect(0xb77ed000, 4096, PROT_READ) = 0 munmap(0xb77cb000, 20075) = 0 brk(0) = 0x943b000 brk(0x945c000) = 0x945c000 uname({sys=&ldquo;Linux&rdquo;, node=&ldquo;OT&rdquo;, &hellip;}) = 0 access(&quot;/proc/net&quot;, R_OK) = 0 access(&quot;/proc/net/unix&quot;, R_OK) = 0 socket(PF_FILE, SOCK_DGRAM, 0) = 3 socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4 access(&quot;/proc/net/if_inet6&quot;, R_OK) = -1 ENOENT (No such file or directory) access(&quot;/proc/net/ax25&quot;, R_OK) = -1 ENOENT (No such file or directory) access(&quot;/proc/net/nr&quot;, R_OK) = -1 ENOENT (No such file or directory) access(&quot;/proc/net/rose&quot;, R_OK) = -1 ENOENT (No such file or directory) access(&quot;/proc/net/ipx&quot;, R_OK) = -1 ENOENT (No such file or directory) access(&quot;/proc/net/appletalk&quot;, R_OK) = -1 ENOENT (No such file or directory) access(&quot;/proc/sys/net/econet&quot;, R_OK) = -1 ENOENT (No such file or directory) access(&quot;/proc/sys/net/ash&quot;, R_OK) = -1 ENOENT (No such file or directory) access(&quot;/proc/net/x25&quot;, R_OK) = -1 ENOENT (No such file or directory) ioctl(4, SIOCSIFHWADDR, {ifr_name=&ldquo;eth0&rdquo;, ifr_hwaddr=00:10:7e:02:52:b6}) = 0 exit_group(0) = ?</p>
<p>What this does is to change the mac address, but after a reboot this change is gone. So where is the mac address stored, you my ask. Normaly each NIC has an eeprom where some specific informations are stored like the mac address. And for linux there exists a nice tool to dump and change the contents of this eeproms – ethtool.</p>
<p>root@OT:~# ethtool -e eth0 Offset Values &mdash;&mdash; &mdash;&mdash; 0x0000 00 10 7e 01 fc 5b 00 00 00 00 01 03 01 47 00 00 0x0010 00 00 00 00 c0 49 01 00 00 00 70 00 00 00 00 00 0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0060 20 00 01 40 0a 41 00 00 00 00 00 00 00 00 00 00 0x0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e2 37</p>
<p>root@OT:~# ifconfig eth0 eth0 Link encap:Ethernet HWaddr 00:10:7e:01:fc:5b inet addr:10.204.120.12 Bcast:10.204.127.255 Mask:255.255.192.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:812 errors:0 dropped:0 overruns:0 frame:0 TX packets:37 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:125002 (122.0 KiB) TX bytes:3195 (3.1 KiB)</p>
<p>Did you see it? We found the place where our mac address is stored 🙂
Lets try to change the mac address directly in the eeprom.</p>
<p>root@OT:<del># ethtool -E eth0 magic 0x1234 offset 0x5 value 0x5c root@OT:</del># ethtool -e eth0 Offset Values &mdash;&mdash; &mdash;&mdash; 0x0000 00 10 7e 01 fc 5c 00 00 00 00 01 03 01 47 00 00 0x0010 00 00 00 00 c0 49 01 00 00 00 70 00 00 00 00 00 0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0060 20 00 01 40 0a 41 00 00 00 00 00 00 00 00 00 00 0x0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e2 36</p>
<p>In theory our new mac address should be available after an reboot.</p>
<p>root@OT:<del># reboot root@OT:</del># ifconfig eth0 eth0 Link encap:Ethernet HWaddr 00:10:7e:01:fc:5c inet addr:10.204.120.12 Bcast:10.204.127.255 Mask:255.255.192.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:482 errors:0 dropped:0 overruns:0 frame:0 TX packets:7 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:32327 (31.5 KiB) TX bytes:986 (986.0 B)</p>
<p>Success – now its time for the big <strong>fat warning:</strong></p>
<p>Every NIC stores the mac address at different offsets etc. so its a good idea
to first look at the datasheet and then make experiments. Also the magic value
needed for ethtool needs to be kown – look at the corresponding linux driver.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Who is wasting my disk space</title>
      <link>https://christian-gmeiner.info/2012-10-13-who-is-wasting-my-disk-space/</link>
      <pubDate>Sat, 13 Oct 2012 11:25:49 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2012-10-13-who-is-wasting-my-disk-space/</guid>
      <description>&lt;p&gt;I think all of us run into this problem… the free space on a storage medium is getting smaller and smaller and you are not really sure why this is the case. For such cases I use a graphical tool to see the biggest space waster – as I am QT guy I am using &lt;a href=&#34;http://methylblue.com/filelight/&#34; title=&#34;filelight&#34;&gt;filelight&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://methylblue.com/filelight/images/filelight-1.0.png&#34; title=&#34;filelight&#34;&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I think all of us run into this problem… the free space on a storage medium is getting smaller and smaller and you are not really sure why this is the case. For such cases I use a graphical tool to see the biggest space waster – as I am QT guy I am using <a href="http://methylblue.com/filelight/" title="filelight">filelight</a>.</p>
<p><img loading="lazy" src="http://methylblue.com/filelight/images/filelight-1.0.png" title="filelight"></p>
]]></content:encoded>
    </item>
    <item>
      <title>em8300: starting from scratch</title>
      <link>https://christian-gmeiner.info/2012-08-07-em8300-starting-from-scratch/</link>
      <pubDate>Tue, 07 Aug 2012 22:09:36 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2012-08-07-em8300-starting-from-scratch/</guid>
      <description>&lt;p&gt;The last two days I found again some time to hack on the em8300/dxr3 driver. I see the end comming of all my work, but I need to change the way I work. I have renamed the old project on github to v4l2-em8300-old and created a new one. Yes you have heard it correctly – a new one. I think that I have enough knowledge to start from scratch.&lt;/p&gt;
&lt;p&gt;The new repository can be found here: &lt;a href=&#34;https://github.com/austriancoder/v4l2-em8300&#34;&gt;https://github.com/austriancoder/v4l2-em8300&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>The last two days I found again some time to hack on the em8300/dxr3 driver. I see the end comming of all my work, but I need to change the way I work. I have renamed the old project on github to v4l2-em8300-old and created a new one. Yes you have heard it correctly – a new one. I think that I have enough knowledge to start from scratch.</p>
<p>The new repository can be found here: <a href="https://github.com/austriancoder/v4l2-em8300">https://github.com/austriancoder/v4l2-em8300</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>interrupt handling in linux device drivers</title>
      <link>https://christian-gmeiner.info/2012-08-07-interrupt-handling-in-linux-device-drivers/</link>
      <pubDate>Tue, 07 Aug 2012 17:04:24 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2012-08-07-interrupt-handling-in-linux-device-drivers/</guid>
      <description>&lt;p&gt;Every developer should know this – and its a free course… for what are you waiting?&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://training.linuxfoundation.org/linux-tutorials/interrupt-handling-in-linux-device-drivers&#34;&gt;Click Me&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Every developer should know this – and its a free course… for what are you waiting?</p>
<p><a href="https://training.linuxfoundation.org/linux-tutorials/interrupt-handling-in-linux-device-drivers">Click Me</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>objdump is your friend</title>
      <link>https://christian-gmeiner.info/2012-07-18-objdump-is-your-friend/</link>
      <pubDate>Wed, 18 Jul 2012 13:41:35 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2012-07-18-objdump-is-your-friend/</guid>
      <description>&lt;p&gt;Lets image you are working on a coreboot port for some mainboard and you are a very glad guy cause you have a jtag interface or something similar and you notice a hang, which could be caused by a never ending loop or some other mysterious stuff – all you know is the current instruction pointer.&lt;/p&gt;
&lt;p&gt;objdump -S ./build/cbfs/fallback/coreboot_ram.elf&lt;/p&gt;
&lt;p&gt;and search for the address of the instruction pointer – may it help you to figure out whats
going on 🙂&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Lets image you are working on a coreboot port for some mainboard and you are a very glad guy cause you have a jtag interface or something similar and you notice a hang, which could be caused by a never ending loop or some other mysterious stuff – all you know is the current instruction pointer.</p>
<p>objdump -S ./build/cbfs/fallback/coreboot_ram.elf</p>
<p>and search for the address of the instruction pointer – may it help you to figure out whats
going on 🙂</p>
]]></content:encoded>
    </item>
    <item>
      <title>Compare Two Filesystems Recursively</title>
      <link>https://christian-gmeiner.info/2012-06-19-compare-two-filesystems-recursively/</link>
      <pubDate>Tue, 19 Jun 2012 10:40:06 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2012-06-19-compare-two-filesystems-recursively/</guid>
      <description>&lt;p&gt;Sometimes it is needed to compare two filesystems, which can be done quite easily:&lt;/p&gt;
&lt;p&gt;diff -rq /mnt/fs1 /mnt/fs2&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Sometimes it is needed to compare two filesystems, which can be done quite easily:</p>
<p>diff -rq /mnt/fs1 /mnt/fs2</p>
]]></content:encoded>
    </item>
    <item>
      <title>Install Grub in a chroot environment</title>
      <link>https://christian-gmeiner.info/2012-01-31-install-grub-in-a-chroot-environment/</link>
      <pubDate>Tue, 31 Jan 2012 12:53:40 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2012-01-31-install-grub-in-a-chroot-environment/</guid>
      <description>&lt;p&gt;Image you destroyed your MBR sector of your hard drive/flash device and you are not able to load grub. You can easily fix this issue from an other Linux based computer. Simply run the following commands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mount /dev/sda1 /mnt/&lt;/li&gt;
&lt;li&gt;mount -t proc none /mnt/proc&lt;/li&gt;
&lt;li&gt;mount -o bind /dev /mnt/dev&lt;/li&gt;
&lt;li&gt;chroot /mnt/ /bin/bash&lt;/li&gt;
&lt;li&gt;/usr/sbin/grub-install –recheck –no-floppy /dev/sda&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this routine it it is also possible to fix UUID problems.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Image you destroyed your MBR sector of your hard drive/flash device and you are not able to load grub. You can easily fix this issue from an other Linux based computer. Simply run the following commands:</p>
<ul>
<li>mount /dev/sda1 /mnt/</li>
<li>mount -t proc none /mnt/proc</li>
<li>mount -o bind /dev /mnt/dev</li>
<li>chroot /mnt/ /bin/bash</li>
<li>/usr/sbin/grub-install –recheck –no-floppy /dev/sda</li>
</ul>
<p>With this routine it it is also possible to fix UUID problems.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Switching</title>
      <link>https://christian-gmeiner.info/2012-01-26-switching/</link>
      <pubDate>Thu, 26 Jan 2012 15:32:39 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2012-01-26-switching/</guid>
      <description>&lt;p&gt;Um eine breitere Masse zu erreichen, wird der Blog geswitcht..&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Starting with this second the whole blog will be in English and it will cover a broader range of topics…&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <content:encoded><![CDATA[<p>Um eine breitere Masse zu erreichen, wird der Blog geswitcht..</p>
<blockquote>
<p>Starting with this second the whole blog will be in English and it will cover a broader range of topics…</p>
</blockquote>
]]></content:encoded>
    </item>
    <item>
      <title>Status Update</title>
      <link>https://christian-gmeiner.info/2011-11-07-status-update/</link>
      <pubDate>Mon, 07 Nov 2011 20:55:47 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2011-11-07-status-update/</guid>
      <description>&lt;p&gt;Hallo zusammen.&lt;/p&gt;
&lt;p&gt;Ich habe schon länger nichts mehr von mir hören lassen, doch nun habe ich ein Update
bezüglich em8300 und dem langsamen aber stätigem Prozess zur Aufnahme in den Mainline Kernel.&lt;/p&gt;
&lt;p&gt;Im Linux Kernel 3.3.0 sind kleine Änderungen für die adv7170 und adb7175 Treiber eingeflossen, welche vom em8300 Treiber benötigt werden. Somit wäre es dann möglich direkt mit dem V4L2 Subdevices zu arbeiten. Was gibt es aber sonst noch zu tun, damit der Prozess irgendwann ein Ende findet?&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Hallo zusammen.</p>
<p>Ich habe schon länger nichts mehr von mir hören lassen, doch nun habe ich ein Update
bezüglich em8300 und dem langsamen aber stätigem Prozess zur Aufnahme in den Mainline Kernel.</p>
<p>Im Linux Kernel 3.3.0 sind kleine Änderungen für die adv7170 und adb7175 Treiber eingeflossen, welche vom em8300 Treiber benötigt werden. Somit wäre es dann möglich direkt mit dem V4L2 Subdevices zu arbeiten. Was gibt es aber sonst noch zu tun, damit der Prozess irgendwann ein Ende findet?</p>
<ul>
<li>bt868 Treiber in den Mainline bringen</li>
<li>VB2</li>
<li>Evtl die DVB-API untersuchen, ob besser als V4L2 API für Ausgbae</li>
<li>Rework des Firmware-Loaders</li>
<li>Locking</li>
<li>…</li>
</ul>
<p>Ich hoffe, dass ich in den nächsten Wochen wieder ein wenig Zeit finde.</p>
]]></content:encoded>
    </item>
    <item>
      <title>v4l2-em8300 - EEPROM dumps</title>
      <link>https://christian-gmeiner.info/2011-05-21-v4l2-em8300-eeprom-dumps/</link>
      <pubDate>Sat, 21 May 2011 21:26:04 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2011-05-21-v4l2-em8300-eeprom-dumps/</guid>
      <description>&lt;p&gt;[ 4204.966614] Sigma Designs EM8300 0000:00:09.0: PCI INT A -&amp;gt; Link[LNKB] -&amp;gt; GSI 5 (level, low) -&amp;gt; IRQ 5
[ 4204.966637] em8300-0: EM8300 8300 (rev 2)
[ 4204.966642] bus: 0, devfn: 72, irq: 5,
[ 4204.966647] memory: 0xcfe00000.
[ 4204.966998] em8300-0: mapped-memory at 0xf9600000
[ 4204.967163] em8300-0: using MTRR
[ 4205.038676] bus 0: i2c scan: found device @ 0x8a  [bt865]
[ 4205.169007] bus 1: i2c scan: found device @ 0xa0  [eeprom]
[ 4205.215170] i2c i2c-2: client [eeprom] registered with bus id 2-0050
[ 4205.268272] full 256-byte eeprom dump:
[ 4205.268284] 00: 10 22 00 00 00 00 00 01 00 00 00 00 00 00 00 00
[ 4205.268299] 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 4205.268313] 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 4205.268327] 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 4205.268340] 40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268355] 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 4205.268368] 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 4205.268381] 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55
[ 4205.268394] 80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268408] 90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268422] a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268436] b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268450] c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268465] d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268479] e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268493] f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268510] em8300-0: detected card: DXR3 with BT865.
[ 4205.268517] em8300-0: Chip revision: 2
[ 4205.276298] bt865 1-0045: chip found @ 0x8a (em8300 i2c driver #0-0)
[ 4205.276910] i2c i2c-1: client [bt865] registered with bus id 1-0045&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>[ 4204.966614] Sigma Designs EM8300 0000:00:09.0: PCI INT A -&gt; Link[LNKB] -&gt; GSI 5 (level, low) -&gt; IRQ 5
[ 4204.966637] em8300-0: EM8300 8300 (rev 2)
[ 4204.966642] bus: 0, devfn: 72, irq: 5,
[ 4204.966647] memory: 0xcfe00000.
[ 4204.966998] em8300-0: mapped-memory at 0xf9600000
[ 4204.967163] em8300-0: using MTRR
[ 4205.038676] bus 0: i2c scan: found device @ 0x8a  [bt865]
[ 4205.169007] bus 1: i2c scan: found device @ 0xa0  [eeprom]
[ 4205.215170] i2c i2c-2: client [eeprom] registered with bus id 2-0050
[ 4205.268272] full 256-byte eeprom dump:
[ 4205.268284] 00: 10 22 00 00 00 00 00 01 00 00 00 00 00 00 00 00
[ 4205.268299] 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 4205.268313] 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 4205.268327] 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 4205.268340] 40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268355] 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 4205.268368] 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 4205.268381] 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55
[ 4205.268394] 80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268408] 90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268422] a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268436] b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268450] c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268465] d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268479] e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268493] f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 4205.268510] em8300-0: detected card: DXR3 with BT865.
[ 4205.268517] em8300-0: Chip revision: 2
[ 4205.276298] bt865 1-0045: chip found @ 0x8a (em8300 i2c driver #0-0)
[ 4205.276910] i2c i2c-1: client [bt865] registered with bus id 1-0045</p>
]]></content:encoded>
    </item>
    <item>
      <title>v4l2-em8300 - Audio Cleanups</title>
      <link>https://christian-gmeiner.info/2011-05-21-v4l2-em8300-audio-cleanups/</link>
      <pubDate>Sat, 21 May 2011 20:27:15 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2011-05-21-v4l2-em8300-audio-cleanups/</guid>
      <description>&lt;p&gt;Hier wieder ein Lebenszeichen vom v4l2-em8300 Projekt.&lt;/p&gt;
&lt;p&gt;Ich habe die letzten zwei Tage genützt um den Audio Teil des Treibers ein wenig aufzuräumen. Ab jetzt wird nur noch ALSA unterstützt und alle Moduloptionen bezüglich
Audio wurden entfernt. Langsam aber sicher habe ich schon viele Teile aufgeräumt und der
Treiber wird immer besser 🙂&lt;/p&gt;
&lt;p&gt;Über die nächsten Schritte in der Entwicklung bin ich mir noch nicht sicher. vbuf2 wäre sicherlich eine Überlegung wert, da ich möglichst viel Kernel-Funktionalität verwenden möchte – macht den Treiber schön klein und übersichtlich. Ich hoffe ich werde in den nächsten Wochen/Monaten wieder einmal Richtig viel Zeit fürs hacken haben.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Hier wieder ein Lebenszeichen vom v4l2-em8300 Projekt.</p>
<p>Ich habe die letzten zwei Tage genützt um den Audio Teil des Treibers ein wenig aufzuräumen. Ab jetzt wird nur noch ALSA unterstützt und alle Moduloptionen bezüglich
Audio wurden entfernt. Langsam aber sicher habe ich schon viele Teile aufgeräumt und der
Treiber wird immer besser 🙂</p>
<p>Über die nächsten Schritte in der Entwicklung bin ich mir noch nicht sicher. vbuf2 wäre sicherlich eine Überlegung wert, da ich möglichst viel Kernel-Funktionalität verwenden möchte – macht den Treiber schön klein und übersichtlich. Ich hoffe ich werde in den nächsten Wochen/Monaten wieder einmal Richtig viel Zeit fürs hacken haben.</p>
<p>Achja – Sourcen gibts <a href="https://github.com/austriancoder/v4l2-em8300">hier.</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Bye Bye BKL</title>
      <link>https://christian-gmeiner.info/2011-05-08-bye-bye-bkl/</link>
      <pubDate>Sun, 08 May 2011 13:02:21 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2011-05-08-bye-bye-bkl/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4ba8216cd90560bc402f52076f64d8546e8aefcb&#34;&gt;http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4ba8216cd90560bc402f52076f64d8546e8aefcb&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4ba8216cd90560bc402f52076f64d8546e8aefcb">http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4ba8216cd90560bc402f52076f64d8546e8aefcb</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Blog is back....</title>
      <link>https://christian-gmeiner.info/2011-04-21-blog-is-back/</link>
      <pubDate>Thu, 21 Apr 2011 15:38:37 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2011-04-21-blog-is-back/</guid>
      <description>&lt;p&gt;Nun finde ich endlich einmal wieder ein wenig Zeit für diesen Blog… und was soll ich sagen, er ist wieder online 🙂 Möge er mit vielen Inhalten gefüllt werden.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Nun finde ich endlich einmal wieder ein wenig Zeit für diesen Blog… und was soll ich sagen, er ist wieder online 🙂 Möge er mit vielen Inhalten gefüllt werden.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Default #define&#39;s vom GCC</title>
      <link>https://christian-gmeiner.info/2010-11-25-default-defines-vom-gcc/</link>
      <pubDate>Thu, 25 Nov 2010 12:04:55 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2010-11-25-default-defines-vom-gcc/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;echo “” | cpp -dD&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dies kann hin und wieder recht nützlich sein.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<blockquote>
<p>echo “” | cpp -dD</p>
</blockquote>
<p>Dies kann hin und wieder recht nützlich sein.</p>
]]></content:encoded>
    </item>
    <item>
      <title>vdr-plugin-dxr3 updates</title>
      <link>https://christian-gmeiner.info/2010-06-28-vdr-plugin-dxr3-updates/</link>
      <pubDate>Mon, 28 Jun 2010 14:10:13 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2010-06-28-vdr-plugin-dxr3-updates/</guid>
      <description>&lt;p&gt;In letzter Zeit hat sich wieder ein wenig was beim Plugin getan. Die OSS Ausgabe wurde nun entfernt um sich ganz der Audioausgabe mittles ALSA zu widmen. Leider gibt es in diesem Bereich
noch ein paar kleinere Probleme, doch ich hoffe diese noch in den Griff zu bekommen. Das Wechseln des Kanales geht nun ohne gröbere Probleme (ALSA spinnt hin und wieder noch) und das Plugin kompiliert auch mit ffmpeg 0.6.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In letzter Zeit hat sich wieder ein wenig was beim Plugin getan. Die OSS Ausgabe wurde nun entfernt um sich ganz der Audioausgabe mittles ALSA zu widmen. Leider gibt es in diesem Bereich
noch ein paar kleinere Probleme, doch ich hoffe diese noch in den Griff zu bekommen. Das Wechseln des Kanales geht nun ohne gröbere Probleme (ALSA spinnt hin und wieder noch) und das Plugin kompiliert auch mit ffmpeg 0.6.</p>
<p>Auf meiner TODO findet sich im Moment folgendes:</p>
<ul>
<li>AC3-Support für ALSA</li>
<li>ALSA Bugfixing</li>
<li>StillPicture</li>
<li>die letzten Sync-Probleme lösen</li>
</ul>
<p>Es wird dann nicht mehr lange gehen, bis ich den buffer-sync-rewrite branch in den trunk mergen werde und dann sollte endlich ein neues langerwartetes Release folgen.</p>
<p>BTW: Es ist zu empfehlen einen modifizierten Treiber für die dxr3 zu verwenden, welchen es hier gibt: <a href="http://hg.assembla.com/em8300-cgmeiner">hg.assembla.com/em8300-cgmeiner</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>alsa</title>
      <link>https://christian-gmeiner.info/2010-06-18-alsa/</link>
      <pubDate>Fri, 18 Jun 2010 22:33:45 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2010-06-18-alsa/</guid>
      <description>&lt;p&gt;Hin und wieder finde ich ein wenig Zeit um am Plugin zu arbeiten. Audio und Video Sync scheint nun recht gut zu funktioneren (noch nicht commited), doch leider bekomme ich oft noch XRuns in alsa. Da ich den oss Support aus dem Plugin entfernen will, ist es sicherlich keine schlechte Idee, den alsa Ausgabe-Treiber zu fixen.&lt;/p&gt;
&lt;p&gt;Zum Glück gibt es die Möglichkeit die XRuns zu debugen – siehe &lt;a href=&#34;http://www.alsa-project.org/main/index.php/XRUN_Debug&#34;&gt;hier&lt;/a&gt;. Ich werde sicherlich noch ein paar nette Studen mit alsa verbringen.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Hin und wieder finde ich ein wenig Zeit um am Plugin zu arbeiten. Audio und Video Sync scheint nun recht gut zu funktioneren (noch nicht commited), doch leider bekomme ich oft noch XRuns in alsa. Da ich den oss Support aus dem Plugin entfernen will, ist es sicherlich keine schlechte Idee, den alsa Ausgabe-Treiber zu fixen.</p>
<p>Zum Glück gibt es die Möglichkeit die XRuns zu debugen – siehe <a href="http://www.alsa-project.org/main/index.php/XRUN_Debug">hier</a>. Ich werde sicherlich noch ein paar nette Studen mit alsa verbringen.</p>
]]></content:encoded>
    </item>
    <item>
      <title>PulseAudio meets vdr-plugin-dxr3</title>
      <link>https://christian-gmeiner.info/2010-03-06-pulseaudio-meets-vdr-plugin-dxr3/</link>
      <pubDate>Sat, 06 Mar 2010 17:18:12 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2010-03-06-pulseaudio-meets-vdr-plugin-dxr3/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;pa-dxr3&#34; loading=&#34;lazy&#34; src=&#34;http://www.christian-gmeiner.info/wordpress/wp-content/uploads/2010/03/pa-dxr3.png&#34; title=&#34;pa-dxr3&#34;&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img alt="pa-dxr3" loading="lazy" src="http://www.christian-gmeiner.info/wordpress/wp-content/uploads/2010/03/pa-dxr3.png" title="pa-dxr3"></p>
]]></content:encoded>
    </item>
    <item>
      <title>Fork-Bombe</title>
      <link>https://christian-gmeiner.info/2010-03-04-fork-bombe/</link>
      <pubDate>Thu, 04 Mar 2010 16:21:13 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2010-03-04-fork-bombe/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;$&amp;gt; PATH=.
$&amp;gt; echo ‘a &amp;amp; a’ &amp;gt; a
$&amp;gt; chmod 755 a; /bin/bash a&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <content:encoded><![CDATA[<blockquote>
<p>$&gt; PATH=.
$&gt; echo ‘a &amp; a’ &gt; a
$&gt; chmod 755 a; /bin/bash a</p>
</blockquote>
]]></content:encoded>
    </item>
    <item>
      <title>Buffer und A/V Sync rewrite</title>
      <link>https://christian-gmeiner.info/2010-02-05-buffer-und-av-sync-rewrite/</link>
      <pubDate>Fri, 05 Feb 2010 14:01:25 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2010-02-05-buffer-und-av-sync-rewrite/</guid>
      <description>&lt;p&gt;Endlich ist es so weit, nach viel Research und vielem Probieren ist der Buffer und A/V Sync rewrite in progress 🙂&lt;/p&gt;
&lt;p&gt;Nun brauche ich sehr viel Feedback bezüglich A/V sync… also alle testen.
&lt;a href=&#34;http://projects.vdr-developer.org/git/?p=vdr-plugin-dxr3.git;a=shortlog;h=refs/heads/buffer-and-sync-rewrite&#34;&gt;http://projects.vdr-developer.org/git/?p=vdr-plugin-dxr3.git;a=shortlog;h=refs/heads/buffer-and-sync-rewrite&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Danke euch allen&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Endlich ist es so weit, nach viel Research und vielem Probieren ist der Buffer und A/V Sync rewrite in progress 🙂</p>
<p>Nun brauche ich sehr viel Feedback bezüglich A/V sync… also alle testen.
<a href="http://projects.vdr-developer.org/git/?p=vdr-plugin-dxr3.git;a=shortlog;h=refs/heads/buffer-and-sync-rewrite">http://projects.vdr-developer.org/git/?p=vdr-plugin-dxr3.git;a=shortlog;h=refs/heads/buffer-and-sync-rewrite</a></p>
<p>Danke euch allen</p>
]]></content:encoded>
    </item>
    <item>
      <title>Linux und HP COLORADO 20GBe(extern)</title>
      <link>https://christian-gmeiner.info/2010-01-19-linux-und-hp-colorado-20gbeextern/</link>
      <pubDate>Tue, 19 Jan 2010 11:31:34 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2010-01-19-linux-und-hp-colorado-20gbeextern/</guid>
      <description>&lt;p&gt;Im Moment bin ich damit konfrontiert, Backups von einem alten exteren Bandlaufwerk wiederherzustellen. Das große Ziel ist es an einen Bruchteil der Daten auf dem Bandlaufwerk Zugang zu bekommen.&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://www.buycoms.com/pic/product/129/14085/TAB6_2.JPG&#34; title=&#34;HP Colorado 20 GB&#34;&gt;Mein Kunde verwendet im Moment einen aktuellen Recher (Quad-Core) mit einem ebenso aktuellen Windows. Blöderweise werden keine Treiber von HP für diese Windows-Version zur Verfügung gestellt und ich musste nach einer Alternative ausschau halten. Und hier glänzt Linux. Ich verwende einen 2.6.32 Kernel und konnte mit diesem erfolgreich das externe Bandlaufwerk (Parallel-Port) erkennen/verwenden.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Im Moment bin ich damit konfrontiert, Backups von einem alten exteren Bandlaufwerk wiederherzustellen. Das große Ziel ist es an einen Bruchteil der Daten auf dem Bandlaufwerk Zugang zu bekommen.</p>
<p><img loading="lazy" src="http://www.buycoms.com/pic/product/129/14085/TAB6_2.JPG" title="HP Colorado 20 GB">Mein Kunde verwendet im Moment einen aktuellen Recher (Quad-Core) mit einem ebenso aktuellen Windows. Blöderweise werden keine Treiber von HP für diese Windows-Version zur Verfügung gestellt und ich musste nach einer Alternative ausschau halten. Und hier glänzt Linux. Ich verwende einen 2.6.32 Kernel und konnte mit diesem erfolgreich das externe Bandlaufwerk (Parallel-Port) erkennen/verwenden.</p>
<p>Dazu müssen folgende Module compiliert und geladen werden:</p>
<ul>
<li>epat</li>
<li>paride</li>
<li>pt</li>
</ul>
<p>Ist das Bandlaufwerk verbunden und die Module geladen sollte folgendes via *dmesg *zu sehen sein.</p>
<blockquote>
<p>paride: epat registered as protocol 0
pt: pt version 1.04, major 96
pt0: Sharing parport0 at 0x378
pt0: epat 1.02, Shuttle EPAT chip c6 at 0x378, mode 2 (8-bit), delay 1
pt0: HP COLORADO 20GBe, master, blocksize 512, 9209 MB</p>
</blockquote>
]]></content:encoded>
    </item>
    <item>
      <title>Es weihnachtet sehr...</title>
      <link>https://christian-gmeiner.info/2009-12-21-es-weihnachtet-sehr/</link>
      <pubDate>Mon, 21 Dec 2009 12:28:17 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-12-21-es-weihnachtet-sehr/</guid>
      <description>&lt;p&gt;int &lt;em&gt;,l; char*I, &lt;em&gt;O[]={&amp;quot;&amp;quot;, &amp;ldquo;gjstu&amp;rdquo;,&amp;ldquo;t&amp;rdquo; &amp;ldquo;fdpoe&amp;rdquo;,&amp;ldquo;uij&amp;rdquo; &amp;ldquo;se&amp;rdquo;,&amp;ldquo;gpvsui&amp;rdquo;, &amp;ldquo;gjgui&amp;rdquo;,&amp;ldquo;t&amp;rdquo; &amp;ldquo;jyui&amp;rdquo;,&amp;ldquo;tfwf&amp;rdquo; &amp;ldquo;oui&amp;rdquo;,&amp;ldquo;fjhiui&amp;rdquo;, &amp;ldquo;ojoui&amp;rdquo;,&amp;ldquo;ufoui&amp;rdquo;, &amp;ldquo;fmfwfoui&amp;rdquo;,&amp;ldquo;uxfmgu&amp;rdquo; &amp;ldquo;i&amp;rdquo;,&amp;ldquo;b!qbsusjehf!jo!&amp;rdquo; &amp;ldquo;b!qfbs!usff/xbxb&amp;rdquo;,&amp;quot;&amp;quot; &amp;ldquo;uxp!uvsumf!epwf&amp;rdquo; &amp;ldquo;t-xb&amp;rdquo;,&amp;ldquo;uisff!gsf&amp;rdquo; &amp;ldquo;odi!ifot-!&amp;rdquo;,&amp;ldquo;gpvs!d&amp;rdquo; &amp;ldquo;bmmjoh!cjset-!&amp;rdquo;,&amp;ldquo;gjwf&amp;rdquo; &amp;ldquo;!hpme!sjoht&amp;lt;xb&amp;rdquo;,&amp;ldquo;tjy!h&amp;rdquo; &amp;ldquo;fftf!b.mbzjoh-!&amp;rdquo;,&amp;ldquo;tfwfo!t&amp;rdquo; &amp;ldquo;xbot!b.txjnnjoh-xb&amp;rdquo;,&amp;ldquo;fjhiu&amp;rdquo; &amp;ldquo;!nbjet!b.njmljoh-!&amp;rdquo;,&amp;ldquo;ojof!mbe&amp;rdquo; &amp;ldquo;jft!ebodjoh-!&amp;rdquo;,&amp;ldquo;ufo!m&amp;rdquo; &amp;ldquo;pset!b.mfbqjoh-xb&amp;rdquo;,&amp;ldquo;fm&amp;rdquo; &amp;ldquo;fwfo!qjqfst!qjqjoh-!&amp;rdquo;,&amp;ldquo;ux&amp;rdquo; &amp;ldquo;fmwf!esvnnfst!esvnnjoh-!&amp;rdquo;,&amp;quot;&amp;quot; &amp;ldquo;Po!uif!&amp;rdquo;,&amp;quot;!ebz!pg!Disjtunbt!n&amp;quot; &amp;ldquo;z!usvf!mpwf!hbwf!up!nfxb&amp;rdquo;,&amp;ldquo;boe&amp;rdquo; &amp;ldquo;!&amp;rdquo;};int putchar(int);int main(void ){while(l&amp;lt;(sizeof O/sizeof&lt;/em&gt;O-2)/2-1){ I=O[&lt;/em&gt;=!&lt;em&gt;?sizeof O/sizeof*O- 3:&lt;/em&gt;&amp;lt;(sizeof(O)/sizeof&lt;em&gt;O-2)/2? sizeof O/sizeof&lt;/em&gt;O-2:&lt;em&gt;==(sizeof( O)/sizeof*O-2)/2?++l,0:&lt;/em&gt;&amp;lt;(sizeof( O)/sizeof(&lt;em&gt;O))-3?(_-1)==(sizeof(O)/ sizeof&lt;/em&gt;O-2)/2?sizeof O/sizeof&lt;em&gt;O-1:&lt;em&gt;-1 :&lt;/em&gt;&amp;lt;sizeof(O)/sizeof&lt;/em&gt;O-2?l+1:_&amp;lt;sizeof(O) /sizeof*O-1?l+(sizeof O/sizeof(&lt;em&gt;O)-2)/2:( sizeof(O)/sizeof&lt;/em&gt;O-2)/2];while(*I){putchar( *I++-1);}} return 0;}&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>int <em>,l; char*I, <em>O[]={&quot;&quot;, &ldquo;gjstu&rdquo;,&ldquo;t&rdquo; &ldquo;fdpoe&rdquo;,&ldquo;uij&rdquo; &ldquo;se&rdquo;,&ldquo;gpvsui&rdquo;, &ldquo;gjgui&rdquo;,&ldquo;t&rdquo; &ldquo;jyui&rdquo;,&ldquo;tfwf&rdquo; &ldquo;oui&rdquo;,&ldquo;fjhiui&rdquo;, &ldquo;ojoui&rdquo;,&ldquo;ufoui&rdquo;, &ldquo;fmfwfoui&rdquo;,&ldquo;uxfmgu&rdquo; &ldquo;i&rdquo;,&ldquo;b!qbsusjehf!jo!&rdquo; &ldquo;b!qfbs!usff/xbxb&rdquo;,&quot;&quot; &ldquo;uxp!uvsumf!epwf&rdquo; &ldquo;t-xb&rdquo;,&ldquo;uisff!gsf&rdquo; &ldquo;odi!ifot-!&rdquo;,&ldquo;gpvs!d&rdquo; &ldquo;bmmjoh!cjset-!&rdquo;,&ldquo;gjwf&rdquo; &ldquo;!hpme!sjoht&lt;xb&rdquo;,&ldquo;tjy!h&rdquo; &ldquo;fftf!b.mbzjoh-!&rdquo;,&ldquo;tfwfo!t&rdquo; &ldquo;xbot!b.txjnnjoh-xb&rdquo;,&ldquo;fjhiu&rdquo; &ldquo;!nbjet!b.njmljoh-!&rdquo;,&ldquo;ojof!mbe&rdquo; &ldquo;jft!ebodjoh-!&rdquo;,&ldquo;ufo!m&rdquo; &ldquo;pset!b.mfbqjoh-xb&rdquo;,&ldquo;fm&rdquo; &ldquo;fwfo!qjqfst!qjqjoh-!&rdquo;,&ldquo;ux&rdquo; &ldquo;fmwf!esvnnfst!esvnnjoh-!&rdquo;,&quot;&quot; &ldquo;Po!uif!&rdquo;,&quot;!ebz!pg!Disjtunbt!n&quot; &ldquo;z!usvf!mpwf!hbwf!up!nfxb&rdquo;,&ldquo;boe&rdquo; &ldquo;!&rdquo;};int putchar(int);int main(void ){while(l&lt;(sizeof O/sizeof</em>O-2)/2-1){ I=O[</em>=!<em>?sizeof O/sizeof*O- 3:</em>&lt;(sizeof(O)/sizeof<em>O-2)/2? sizeof O/sizeof</em>O-2:<em>==(sizeof( O)/sizeof*O-2)/2?++l,0:</em>&lt;(sizeof( O)/sizeof(<em>O))-3?(_-1)==(sizeof(O)/ sizeof</em>O-2)/2?sizeof O/sizeof<em>O-1:<em>-1 :</em>&lt;sizeof(O)/sizeof</em>O-2?l+1:_&lt;sizeof(O) /sizeof*O-1?l+(sizeof O/sizeof(<em>O)-2)/2:( sizeof(O)/sizeof</em>O-2)/2];while(*I){putchar( *I++-1);}} return 0;}</p>
]]></content:encoded>
    </item>
    <item>
      <title>VDR 1.7 Statusupdate [Upd]</title>
      <link>https://christian-gmeiner.info/2009-12-05-vdr-1-7-statusupdate/</link>
      <pubDate>Sat, 05 Dec 2009 21:49:17 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-12-05-vdr-1-7-statusupdate/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://projects.vdr-developer.org/git/?p=vdr-plugin-dxr3.git;a=commitdiff;h=41f0211ca48e2c5a5af1fe41f9af644012fe91c4&#34;&gt;41f0211ca48e2c5a5af1fe41f9af644012fe91c4&lt;/a&gt; – das ist der Commit der Audioprobleme mit VDR 1.7
korrigiert. Noch gibt av_log eine Warnung aus:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[mp3 @ 0x9e70a60]incorrect frame size&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Diese kann ignoriert werden… die Ursache ist mir bekannt, doch ich bin mir noch nicht sicher, wie
ich das am schönsten löse 🙂&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Der Bug 169 ist nun mit Commit 961b570ff897b54beabdcb4c54e59049203ce10a gefixt.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><a href="http://projects.vdr-developer.org/git/?p=vdr-plugin-dxr3.git;a=commitdiff;h=41f0211ca48e2c5a5af1fe41f9af644012fe91c4">41f0211ca48e2c5a5af1fe41f9af644012fe91c4</a> – das ist der Commit der Audioprobleme mit VDR 1.7
korrigiert. Noch gibt av_log eine Warnung aus:</p>
<blockquote>
<p>[mp3 @ 0x9e70a60]incorrect frame size</p>
</blockquote>
<p>Diese kann ignoriert werden… die Ursache ist mir bekannt, doch ich bin mir noch nicht sicher, wie
ich das am schönsten löse 🙂</p>
<p><strong>Update:</strong></p>
<p>Der Bug 169 ist nun mit Commit 961b570ff897b54beabdcb4c54e59049203ce10a gefixt.</p>
]]></content:encoded>
    </item>
    <item>
      <title>audiodecoder und 1.7.10</title>
      <link>https://christian-gmeiner.info/2009-12-03-audiodecoder-und-1-7-10/</link>
      <pubDate>Thu, 03 Dec 2009 12:41:43 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-12-03-audiodecoder-und-1-7-10/</guid>
      <description>&lt;p&gt;Endlich habe ich auf meinem VDR die Version 1.7.10 installiert und schon bin ich mir sicher,
was ich die nächsten Stunden zu machen habe.
So wie es aussieht braucht der audiodecoder eine Grunderneuerung, damit die Soundprobleme
mit der 1.7.10 Version gefixt werden können. Ich nutzte diese Gelegenheit um den Release einer
neuen Version zu verschieben. Des Weiterem gibt es auch noch ein paar Bugreports, die ich in Angriff
nehmen sollte.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Endlich habe ich auf meinem VDR die Version 1.7.10 installiert und schon bin ich mir sicher,
was ich die nächsten Stunden zu machen habe.
So wie es aussieht braucht der audiodecoder eine Grunderneuerung, damit die Soundprobleme
mit der 1.7.10 Version gefixt werden können. Ich nutzte diese Gelegenheit um den Release einer
neuen Version zu verschieben. Des Weiterem gibt es auch noch ein paar Bugreports, die ich in Angriff
nehmen sollte.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Brauche eure Hilfe</title>
      <link>https://christian-gmeiner.info/2009-11-17-brauche-eure-hilfe/</link>
      <pubDate>Tue, 17 Nov 2009 11:33:11 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-11-17-brauche-eure-hilfe/</guid>
      <description>&lt;p&gt;Hallo zusammen,&lt;/p&gt;
&lt;p&gt;meine Schwester benötigt für ihre &lt;span style=&#34;letter-spacing: 0px;&#34;&gt;Bachelorarbeit zum Thema „Der Einsatz von Social Media beim Verkauf von Merchandise-Produkten − Dargestellt an einem Praxisbeispiel aus der Musikbranche“ eure Hilfe.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;letter-spacing: 0px;&#34;&gt;Einfach &lt;a href=&#34;http://vote.sinceyouaredead.at&#34;&gt;http://vote.sinceyouaredead.at&lt;/a&gt; besuchen und sich 10 Minuten Zeit nehmen um die Umfrage zu beantworten. Unter allen Teilnehmer – EMail-Adresse vorausgesetzt – werden Preise verlost.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;letter-spacing: 0px;&#34;&gt;Danke!
&lt;/span&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Hallo zusammen,</p>
<p>meine Schwester benötigt für ihre <span style="letter-spacing: 0px;">Bachelorarbeit zum Thema „Der Einsatz von Social Media beim Verkauf von Merchandise-Produkten − Dargestellt an einem Praxisbeispiel aus der Musikbranche“ eure Hilfe.</span></p>
<p><span style="letter-spacing: 0px;">Einfach <a href="http://vote.sinceyouaredead.at">http://vote.sinceyouaredead.at</a> besuchen und sich 10 Minuten Zeit nehmen um die Umfrage zu beantworten. Unter allen Teilnehmer – EMail-Adresse vorausgesetzt – werden Preise verlost.</span></p>
<p><span style="letter-spacing: 0px;">Danke!
</span></p>
]]></content:encoded>
    </item>
    <item>
      <title>London ich komme...</title>
      <link>https://christian-gmeiner.info/2009-10-23-london-ich-komme/</link>
      <pubDate>Fri, 23 Oct 2009 21:04:16 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-10-23-london-ich-komme/</guid>
      <description>&lt;p&gt;Die nächsten 5 Tage bin ich auf kurz Urlaub in London und werde aus diesem Grund unwahrscheinlich Mails beantworten…&lt;/p&gt;
&lt;p&gt;Schönes Wochenende&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Die nächsten 5 Tage bin ich auf kurz Urlaub in London und werde aus diesem Grund unwahrscheinlich Mails beantworten…</p>
<p>Schönes Wochenende</p>
]]></content:encoded>
    </item>
    <item>
      <title>StillPictures</title>
      <link>https://christian-gmeiner.info/2009-10-16-stillpictures/</link>
      <pubDate>Fri, 16 Oct 2009 11:53:07 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-10-16-stillpictures/</guid>
      <description>&lt;p&gt;Hallo,&lt;/p&gt;
&lt;p&gt;endlich habe ich mich getraut, den alten SpuEncoder durch den neuen zu ersetzten, auch wenn es noch zu Problemen
kommen kann. Doch dies war ein wichtiger Schritt in die richtige Richtung.&lt;/p&gt;
&lt;p&gt;Bevor ich die bekannten Bugs im SpuEncoder behebe, brauche ich ein bisschen Abstand und von dieser Thematik und bin dabei die StillPicture-Methode zu fixen. Wie es sich herausstellt ist das Vorhaben – wie sollte es anders sein – nicht ganz trivial. Zu aller erst muss ich mich mit den verschiedenen Playmodes vertraut machen und da habe ich schon ein paar Dinge gefunden, die im Treiber nicht vorhanden sind. Ein Beispiel wäre hier  EM8300_PLAYMODE_SINGLESTEP. Ist zwar in der em8300.h vorhanden, wird aber vom Treiber nicht unterstützt.
Das wird noch eine interessante Reise in das Land der em8300 werden. Es wäre schön, wenn es eine ordentlich dokumentierte API für die Treiber geben würde. Bin es aber eh schon gewohnt immer alles auszuprobieren zu müssen und nach 1-2 Tagen hackings eine Lösung zu finden.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Hallo,</p>
<p>endlich habe ich mich getraut, den alten SpuEncoder durch den neuen zu ersetzten, auch wenn es noch zu Problemen
kommen kann. Doch dies war ein wichtiger Schritt in die richtige Richtung.</p>
<p>Bevor ich die bekannten Bugs im SpuEncoder behebe, brauche ich ein bisschen Abstand und von dieser Thematik und bin dabei die StillPicture-Methode zu fixen. Wie es sich herausstellt ist das Vorhaben – wie sollte es anders sein – nicht ganz trivial. Zu aller erst muss ich mich mit den verschiedenen Playmodes vertraut machen und da habe ich schon ein paar Dinge gefunden, die im Treiber nicht vorhanden sind. Ein Beispiel wäre hier  EM8300_PLAYMODE_SINGLESTEP. Ist zwar in der em8300.h vorhanden, wird aber vom Treiber nicht unterstützt.
Das wird noch eine interessante Reise in das Land der em8300 werden. Es wäre schön, wenn es eine ordentlich dokumentierte API für die Treiber geben würde. Bin es aber eh schon gewohnt immer alles auszuprobieren zu müssen und nach 1-2 Tagen hackings eine Lösung zu finden.</p>
<p>greets</p>
]]></content:encoded>
    </item>
    <item>
      <title>Ticket #166</title>
      <link>https://christian-gmeiner.info/2009-10-05-ticket-166/</link>
      <pubDate>Mon, 05 Oct 2009 15:28:08 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-10-05-ticket-166/</guid>
      <description>&lt;p&gt;Im Moment bin ich dabei &lt;a href=&#34;http://projects.vdr-developer.org/issues/show/166&#34;&gt;diesen Bugrepor&lt;/a&gt;t zu fixen und habe auch schon herausgefunden, was falsch läuft.
Nun bin ich soweit, dass ich alle Areas des OSD auch probiere auszugeben. Und zwar encode ich im Moment
jede Area und schreibe die Daten an das SPU-Subdevice. Nun dachte ich mir, dass die anzeigten OSD-Teile auch so lange
angezeigt werden, bis ich das OSD von Hand cleane. Doch dies scheint leider nicht zu funktionieren. Im Moment
flackern alle Areas eines OSD auf dem TV… sprich beim Schreiben einer Area, wird das bereits angezeigte OSD gelöscht.
Mal schauen, ob ich das einfach fixen kann… ansonsten wird es schwieriger….&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Im Moment bin ich dabei <a href="http://projects.vdr-developer.org/issues/show/166">diesen Bugrepor</a>t zu fixen und habe auch schon herausgefunden, was falsch läuft.
Nun bin ich soweit, dass ich alle Areas des OSD auch probiere auszugeben. Und zwar encode ich im Moment
jede Area und schreibe die Daten an das SPU-Subdevice. Nun dachte ich mir, dass die anzeigten OSD-Teile auch so lange
angezeigt werden, bis ich das OSD von Hand cleane. Doch dies scheint leider nicht zu funktionieren. Im Moment
flackern alle Areas eines OSD auf dem TV… sprich beim Schreiben einer Area, wird das bereits angezeigte OSD gelöscht.
Mal schauen, ob ich das einfach fixen kann… ansonsten wird es schwieriger….</p>
<p>Stay tuned</p>
]]></content:encoded>
    </item>
    <item>
      <title>Tester gesucht</title>
      <link>https://christian-gmeiner.info/2009-09-30-tester-gesucht/</link>
      <pubDate>Wed, 30 Sep 2009 08:43:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-09-30-tester-gesucht/</guid>
      <description>&lt;p&gt;Hallo zusammen,&lt;/p&gt;
&lt;p&gt;ich bin auf der Suche nach Testern für das neue OSD.  Dazu einfach die aktuelle Entwicklerversion
des Plugins herunterladen, installieren und testen.&lt;/p&gt;
&lt;p&gt;Die Entwicklerversion ist entweder &lt;a href=&#34;http://projects.vdr-developer.org/git/?p=vdr-plugin-dxr3.git;a=snapshot;h=4e6085d8aa2f11c9decba9674ef9152ce6292f65;sf=tgz&#34;&gt;hier&lt;/a&gt; oder via git unter &lt;code&gt;git://&amp;lt;a href=&amp;quot;http://community.xeatre.tv/vdr-plugin-dxr3.git&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;community.xeatre.tv/vdr-plugin-&amp;lt;span&amp;gt;dxr3&amp;lt;/span&amp;gt;.git&amp;lt;/a&amp;gt;&lt;/code&gt;
verfügbar.
Probleme, Wünsche etc. bitte unter &lt;a href=&#34;http://projects.vdr-developer.org/projects/show/plg-dxr3&#34;&gt;http://projects.vdr-developer.org/projects/show/plg-dxr3&lt;/a&gt; melden.&lt;/p&gt;
&lt;p&gt;Danke an Alle&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Hallo zusammen,</p>
<p>ich bin auf der Suche nach Testern für das neue OSD.  Dazu einfach die aktuelle Entwicklerversion
des Plugins herunterladen, installieren und testen.</p>
<p>Die Entwicklerversion ist entweder <a href="http://projects.vdr-developer.org/git/?p=vdr-plugin-dxr3.git;a=snapshot;h=4e6085d8aa2f11c9decba9674ef9152ce6292f65;sf=tgz">hier</a> oder via git unter <code>git://&lt;a href=&quot;http://community.xeatre.tv/vdr-plugin-dxr3.git&quot; target=&quot;_blank&quot;&gt;community.xeatre.tv/vdr-plugin-&lt;span&gt;dxr3&lt;/span&gt;.git&lt;/a&gt;</code>
verfügbar.
Probleme, Wünsche etc. bitte unter <a href="http://projects.vdr-developer.org/projects/show/plg-dxr3">http://projects.vdr-developer.org/projects/show/plg-dxr3</a> melden.</p>
<p>Danke an Alle</p>
]]></content:encoded>
    </item>
    <item>
      <title>OSD Update [UP2]</title>
      <link>https://christian-gmeiner.info/2009-09-24-osd-update/</link>
      <pubDate>Thu, 24 Sep 2009 18:47:24 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-09-24-osd-update/</guid>
      <description>&lt;p&gt;Hier mal ein Foto direkt von meinem TV. Zu sehen ist der aktuelle Stand des Plugins mit dem OSD-rewrite. OSD Regionen werden erkannt doch im Bitstream scheint noch was nicht ganz okay zu sein. Mal schauen wie lange ich dafür noch brauche.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.christian-gmeiner.info/wordpress/wp-content/uploads/2009/09/l_1600_1200_FF74AA24-3B9C-4B3D-9FFE-D2ABFF07F8F7.jpeg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://www.christian-gmeiner.info/wordpress/wp-content/uploads/2009/09/l_1600_1200_FF74AA24-3B9C-4B3D-9FFE-D2ABFF07F8F7.jpeg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hier noch zwei Screenshots, die das kleine Tool gtkspu zeigen, welches einen SPU-Datenstrom darstellen kann. Hier sieht das Ganze nicht so schlecht aus. Bei meinem Source stimmen auf jeden Fall die Farben nicht.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Hier mal ein Foto direkt von meinem TV. Zu sehen ist der aktuelle Stand des Plugins mit dem OSD-rewrite. OSD Regionen werden erkannt doch im Bitstream scheint noch was nicht ganz okay zu sein. Mal schauen wie lange ich dafür noch brauche.</p>
<p><a href="http://www.christian-gmeiner.info/wordpress/wp-content/uploads/2009/09/l_1600_1200_FF74AA24-3B9C-4B3D-9FFE-D2ABFF07F8F7.jpeg"><img loading="lazy" src="http://www.christian-gmeiner.info/wordpress/wp-content/uploads/2009/09/l_1600_1200_FF74AA24-3B9C-4B3D-9FFE-D2ABFF07F8F7.jpeg"></a></p>
<p><strong>Update</strong></p>
<p>Hier noch zwei Screenshots, die das kleine Tool gtkspu zeigen, welches einen SPU-Datenstrom darstellen kann. Hier sieht das Ganze nicht so schlecht aus. Bei meinem Source stimmen auf jeden Fall die Farben nicht.</p>
<p><img alt="snap1" loading="lazy" src="http://www.christian-gmeiner.info/wordpress/wp-content/uploads/2009/09/snap1-1024x534.jpg" title="snap1"></p>
<p><img alt="snap2" loading="lazy" src="http://www.christian-gmeiner.info/wordpress/wp-content/uploads/2009/09/snap2-1024x415.jpg" title="snap2"></p>
<p><strong>Update 2</strong></p>
<p>Ich habe nun zwei kleine Bugs behoben und nun schaut das ganze schon recht gut aus. Die letzten Fehler
werde ich in den nächsten Tagen beheben und dann folgt ein git push und jeder kann testen.</p>
<p><img alt="l_1600_1200_C637C1D1-46BF-4E90-AB16-1D668BC9F475.jpeg" loading="lazy" src="http://www.christian-gmeiner.info/wordpress/wp-content/uploads/2009/09/l_1600_1200_C637C1D1-46BF-4E90-AB16-1D668BC9F475.jpeg" title="l_1600_1200_C637C1D1-46BF-4E90-AB16-1D668BC9F475.jpeg"></p>
]]></content:encoded>
    </item>
    <item>
      <title>Ein Update</title>
      <link>https://christian-gmeiner.info/2009-09-12-ein-update/</link>
      <pubDate>Sat, 12 Sep 2009 20:55:47 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-09-12-ein-update/</guid>
      <description>&lt;p&gt;Jaja… lange ist es her, der letzte Eintrag und scheinbar hat sich immer noch nicht viel geändert. Immer diese Versprechen auf mehr… auf ein besseres Plugin. Nun es stimmt, ich habe 4 verschiedene Checkouts des Source, die alle andere Problembereiche verbessern.&lt;/p&gt;
&lt;p&gt;Nun da meine Masterarbeit abgeschlossen ist und ich am kommenden Donnerstag meine Masterprüfung (mündlich) habe, finde ich langsam wieder Zeit für das Plugin. Und das erste das unbedingt gefixt werden muss ist das OSD. Der Source wird leichter verständlich und ist übersichtlicher. Was noch fehlt ist das Handling für Bpp != 2 und hier mache ich diesen Moment gute Fortschritte.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Jaja… lange ist es her, der letzte Eintrag und scheinbar hat sich immer noch nicht viel geändert. Immer diese Versprechen auf mehr… auf ein besseres Plugin. Nun es stimmt, ich habe 4 verschiedene Checkouts des Source, die alle andere Problembereiche verbessern.</p>
<p>Nun da meine Masterarbeit abgeschlossen ist und ich am kommenden Donnerstag meine Masterprüfung (mündlich) habe, finde ich langsam wieder Zeit für das Plugin. Und das erste das unbedingt gefixt werden muss ist das OSD. Der Source wird leichter verständlich und ist übersichtlicher. Was noch fehlt ist das Handling für Bpp != 2 und hier mache ich diesen Moment gute Fortschritte.</p>
<p>Stay tuned….</p>
]]></content:encoded>
    </item>
    <item>
      <title>Zapping ohne Ruckler</title>
      <link>https://christian-gmeiner.info/2009-06-13-zapping-ohne-ruckler/</link>
      <pubDate>Sat, 13 Jun 2009 01:21:47 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-06-13-zapping-ohne-ruckler/</guid>
      <description>&lt;p&gt;Hallo zusammen,&lt;/p&gt;
&lt;p&gt;mittlerweile ist viel passiert und der syncbuffer und das demuxdevice sind komplett aus dem Source verschwunden. Und mein erstes Teilziel ist erreicht. Ich kann zwischen den Kanälen zappen und ich bekomme jedes mal ohne Tonknister und Co. einen sauberen Sound und das mit guten Umschaltzeiten.
Eine Problem für die vielen Probleme mit dem Sync waren dann bemerkbar, als ein OSD angezeigt wurde… habe die Ausgabe abgedreht und siehe da… um Welten besser.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Hallo zusammen,</p>
<p>mittlerweile ist viel passiert und der syncbuffer und das demuxdevice sind komplett aus dem Source verschwunden. Und mein erstes Teilziel ist erreicht. Ich kann zwischen den Kanälen zappen und ich bekomme jedes mal ohne Tonknister und Co. einen sauberen Sound und das mit guten Umschaltzeiten.
Eine Problem für die vielen Probleme mit dem Sync waren dann bemerkbar, als ein OSD angezeigt wurde… habe die Ausgabe abgedreht und siehe da… um Welten besser.</p>
<p>Als nächstes möchte ich Video auf den TV zaubern und das Lippen-Syncron..
see ya</p>
]]></content:encoded>
    </item>
    <item>
      <title>Mal ein kleines Update</title>
      <link>https://christian-gmeiner.info/2009-05-20-mal-ein-kleines-update/</link>
      <pubDate>Wed, 20 May 2009 12:18:14 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-05-20-mal-ein-kleines-update/</guid>
      <description>&lt;p&gt;Meine Masterarbeit befindet sich in einem guten Status und nun habe ich wieder einmal ein wenig
Zeit für das Plugin gefunden. Der neue SpuEncoder funktioniert schon recht gut, nur bei mehr als
4 Farben steigt er aus. Habe schon alles vorbereit um mit 16 Farben zu arbeiten, doch mir fehlt noch
ein Algorithmus, wie ich am besten die unterschiedlichen Regionen erkennen kann.&lt;/p&gt;
&lt;p&gt;Eine Region hat einen Start- u. Endzeile und wird genauer ducht Sektionen bestimmt – mittels Startreihe.
Ich hoffe ich finde bzw. erfinde solch einen Erkennungsalgorithmus… dann wäre das OSD wesentlich besser.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Meine Masterarbeit befindet sich in einem guten Status und nun habe ich wieder einmal ein wenig
Zeit für das Plugin gefunden. Der neue SpuEncoder funktioniert schon recht gut, nur bei mehr als
4 Farben steigt er aus. Habe schon alles vorbereit um mit 16 Farben zu arbeiten, doch mir fehlt noch
ein Algorithmus, wie ich am besten die unterschiedlichen Regionen erkennen kann.</p>
<p>Eine Region hat einen Start- u. Endzeile und wird genauer ducht Sektionen bestimmt – mittels Startreihe.
Ich hoffe ich finde bzw. erfinde solch einen Erkennungsalgorithmus… dann wäre das OSD wesentlich besser.</p>
<p>Cheers</p>
]]></content:encoded>
    </item>
    <item>
      <title>Pes-Parser rewrite done</title>
      <link>https://christian-gmeiner.info/2009-04-19-pes-parser-rewrite-done/</link>
      <pubDate>Sun, 19 Apr 2009 19:33:23 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-04-19-pes-parser-rewrite-done/</guid>
      <description>&lt;p&gt;Habe soeben mal einen Tree gepusht und darin enthalten ist ein der neue Pes-Parser. Desweiteren habe ich den alten
Source ordentlich aufgeräumt. Dabei bin ich schon auf die nächste Baustelle getroffen.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;cFixedLengthFrame oder warum doppele Datenhaltung&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Im Moment wird aus dem Pes-Stream ein cDxr3PesFrame definiert, welcher wichtige Informationen ala Pes, Payload etc.
beinhaltet. Dann wird – unter gewissen Umständen – dieser cDxr3PesFrame in einen cFixedLengthFrame kopiert und im
SyncBuffer verarbeitet.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Habe soeben mal einen Tree gepusht und darin enthalten ist ein der neue Pes-Parser. Desweiteren habe ich den alten
Source ordentlich aufgeräumt. Dabei bin ich schon auf die nächste Baustelle getroffen.</p>
<blockquote>
<p>cFixedLengthFrame oder warum doppele Datenhaltung</p>
</blockquote>
<p>Im Moment wird aus dem Pes-Stream ein cDxr3PesFrame definiert, welcher wichtige Informationen ala Pes, Payload etc.
beinhaltet. Dann wird – unter gewissen Umständen – dieser cDxr3PesFrame in einen cFixedLengthFrame kopiert und im
SyncBuffer verarbeitet.</p>
<p>Nun habe ich die Idee, den cDxr3PesFrame überall zu verwenden… aus diesem Grund werde ich als erstes die Datenstruktur
zur Speicherung von Frames im Syncbuffer auf eine LinkedList abändern. Danach wird schrittweise der cFixedLengthFrame
eliminiert. Diese Designänderung macht den Ablauf im Plugin wesentlich einfacher.</p>
<p>Pes-Stream —&gt; wird zu —&gt; cDxr3PesFrame —&gt; wird in SynBuffer gespeichert —&gt; wird via Output-Thread ausgegeben</p>
<p>Mal schauen, wie lange ich für die Änderungen brauche und viele neue Bugs ich einscheusen kann 🙂</p>
]]></content:encoded>
    </item>
    <item>
      <title>Ein Vergleich - neuer vs. alter Spu Osd Code</title>
      <link>https://christian-gmeiner.info/2009-04-15-ein-vergleich-neuer-vs-alter-spu-osd-code/</link>
      <pubDate>Wed, 15 Apr 2009 22:07:46 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-04-15-ein-vergleich-neuer-vs-alter-spu-osd-code/</guid>
      <description>&lt;p&gt;Hallo zusammen,&lt;/p&gt;
&lt;p&gt;im moment Arbeite ich daran den neuen Pes-Parser in das Plugin zu integrieren. Leider ist das nicht immer so einfach
um die Gefahr, neue Bugs zu erzeugen, ist relativ hoch. Ich muss mir langsam auch mal Gedanken machen, wann
ich ein Art Beta-Version machen sollte. Ich denke, dass dies noch so lange dauern wird, bis auch das Buffering und Syncing
überarbeitet ist.&lt;/p&gt;
&lt;p&gt;Nun mal ein Blick in die Vergangenheit 🙂
Ich habe vor mehreren Monaten begonnen, das Plugin von Grundauf neu zu schreiben… unter anderem auch das OSD… ich verwendete
zum testen gtkspu und ich denke der Unterschied ist sehr gut sichtbar.  Oben der neue OSD Code und unten der alte OSD Code.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Hallo zusammen,</p>
<p>im moment Arbeite ich daran den neuen Pes-Parser in das Plugin zu integrieren. Leider ist das nicht immer so einfach
um die Gefahr, neue Bugs zu erzeugen, ist relativ hoch. Ich muss mir langsam auch mal Gedanken machen, wann
ich ein Art Beta-Version machen sollte. Ich denke, dass dies noch so lange dauern wird, bis auch das Buffering und Syncing
überarbeitet ist.</p>
<p>Nun mal ein Blick in die Vergangenheit 🙂
Ich habe vor mehreren Monaten begonnen, das Plugin von Grundauf neu zu schreiben… unter anderem auch das OSD… ich verwendete
zum testen gtkspu und ich denke der Unterschied ist sehr gut sichtbar.  Oben der neue OSD Code und unten der alte OSD Code.</p>
<p>Bis diese Änderungen in das Plugin einfließen, werden aber noch ein paar Monate vergehen… da es noch sehr viele andere Dinge zu machen gibt… das wird wohl in einem fast rewritte des Plguins enden.</p>
<p>Desweiten bin ich im Moment auch mit meiner Master-Arbeit beschäftigt und das hat mehr Prioritäten als alles andere, auch wenn ich
an gewissen Tagen lieder etwas anderes machen würde, als mich mit Java und AVR32 auseinander zu setzten.</p>
<p><img alt="new_vs_old" loading="lazy" src="http://www.christian-gmeiner.info/wordpress/wp-content/uploads/2009/04/new_vs_old-1024x743.jpg" title="new_vs_old"></p>
]]></content:encoded>
    </item>
    <item>
      <title>Buffering und Sync</title>
      <link>https://christian-gmeiner.info/2009-03-23-buffering-und-sync/</link>
      <pubDate>Mon, 23 Mar 2009 19:41:33 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-03-23-buffering-und-sync/</guid>
      <description>&lt;p&gt;Nachdem ich nun einen schlanken und gut dokumintierten und v.a. funktionierenden Pes-Parser habe, bin ich
mir am überlegen, wie ich nun weitermachen sollte. Ich könnte nun Glue-Code  dem neuen Pes-Parser hinzufügen
und Stück für Stück so weiter machen wie bis her, oder ich mache einfach dies:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;git rm dxr3syncbuffer.c
git rm dxr3syncbuffer.h
git rm dxr3demuxdevice.c
git rm dxr3demuxdevice.h&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Das ist zwar eine brachialte Art und Weise, doch irgnedwann muss man das Buffering und Syncing neu schreiben. Nun
geht es darum, alles wieder ohne Fehler zum compilieren zu bringen und dann das Plugin wieder so funktionstüchtig zu
machen wie die 0.2.9 Version. Es werden große Änderungen sein, doch es wird sich auszahlen.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Nachdem ich nun einen schlanken und gut dokumintierten und v.a. funktionierenden Pes-Parser habe, bin ich
mir am überlegen, wie ich nun weitermachen sollte. Ich könnte nun Glue-Code  dem neuen Pes-Parser hinzufügen
und Stück für Stück so weiter machen wie bis her, oder ich mache einfach dies:</p>
<blockquote>
<p>git rm dxr3syncbuffer.c
git rm dxr3syncbuffer.h
git rm dxr3demuxdevice.c
git rm dxr3demuxdevice.h</p>
</blockquote>
<p>Das ist zwar eine brachialte Art und Weise, doch irgnedwann muss man das Buffering und Syncing neu schreiben. Nun
geht es darum, alles wieder ohne Fehler zum compilieren zu bringen und dann das Plugin wieder so funktionstüchtig zu
machen wie die 0.2.9 Version. Es werden große Änderungen sein, doch es wird sich auszahlen.</p>
]]></content:encoded>
    </item>
    <item>
      <title>PesFrame reworking</title>
      <link>https://christian-gmeiner.info/2009-03-23-pesframe-reworking/</link>
      <pubDate>Mon, 23 Mar 2009 10:34:58 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-03-23-pesframe-reworking/</guid>
      <description>&lt;p&gt;Heute habe ich wieder ein wenig Zeit gefunden, um am dxr3 Plugin zu arbeiten und bin im Moment
an der PesFrame-Baustelle dran. Der jetzige Source ist leider nicht gerade sehr übersichtlich und
verständlich geschrieben. Aus diesem Grund wird die PesFrame KLasse komplett neu geschrieben und
nach meiner Einschätzung wesentlich besser zu verstehen und auch von der Laufzeit optimiert, da kein
cDxr3SafeArray verwendet wird – wozu auch.&lt;/p&gt;
&lt;p&gt;Ich bin mir auch im klaren darüber, dass die jetzige git Version evt nicht so stabil läuft wie die 0.2.9, doch
das ist nur normal, wenn man viele Dinge über den Haufen wirft und neu erfindet. Gut Ding brauch seine Zeit.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Heute habe ich wieder ein wenig Zeit gefunden, um am dxr3 Plugin zu arbeiten und bin im Moment
an der PesFrame-Baustelle dran. Der jetzige Source ist leider nicht gerade sehr übersichtlich und
verständlich geschrieben. Aus diesem Grund wird die PesFrame KLasse komplett neu geschrieben und
nach meiner Einschätzung wesentlich besser zu verstehen und auch von der Laufzeit optimiert, da kein
cDxr3SafeArray verwendet wird – wozu auch.</p>
<p>Ich bin mir auch im klaren darüber, dass die jetzige git Version evt nicht so stabil läuft wie die 0.2.9, doch
das ist nur normal, wenn man viele Dinge über den Haufen wirft und neu erfindet. Gut Ding brauch seine Zeit.</p>
<p>PS: Alsa Audioausgabe ist hin und wieder buggy und bei einigen funktioniert garnix – keine Angst, dass steht auch
auf meiner TODO 🙂</p>
]]></content:encoded>
    </item>
    <item>
      <title>Alsa Support</title>
      <link>https://christian-gmeiner.info/2009-02-26-alsa-support/</link>
      <pubDate>Thu, 26 Feb 2009 12:19:49 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2009-02-26-alsa-support/</guid>
      <description>&lt;p&gt;Nachdem das letzte Semester sehr zeitintensiv war fand ich leider sehr wenig Zeit für opensource Projekte.
Doch im Moment genieße ich die freie Zeit die zur Verfügung habe und stecke im Moment viel Zeit in das
vdr-plugin-dxr3.&lt;/p&gt;
&lt;p&gt;Mein großes Ziel ist zum einen Alsa für die Soundausgabe zu unterstützten und zum anderen das Plugin
wesentlich stabiler zu machen.
Alsa funktioniert schon recht gut, auch wenn es noch Probleme beim Umschalten geben kann und Digital PCM
und AC3 noch nicht unterstützt werden. Doch ich bin auf dem richtigen Weg.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Nachdem das letzte Semester sehr zeitintensiv war fand ich leider sehr wenig Zeit für opensource Projekte.
Doch im Moment genieße ich die freie Zeit die zur Verfügung habe und stecke im Moment viel Zeit in das
vdr-plugin-dxr3.</p>
<p>Mein großes Ziel ist zum einen Alsa für die Soundausgabe zu unterstützten und zum anderen das Plugin
wesentlich stabiler zu machen.
Alsa funktioniert schon recht gut, auch wenn es noch Probleme beim Umschalten geben kann und Digital PCM
und AC3 noch nicht unterstützt werden. Doch ich bin auf dem richtigen Weg.</p>
<p>Ich bin immer sehr froh über Testberichte 🙂
Die aktuellen Sourcen gibts hier: <a href="http://projects.vdr-developer.org/git/?p=vdr-plugin-dxr3.git;a=summary">http://projects.vdr-developer.org/git/?p=vdr-plugin-dxr3.git;a=summary</a></p>
<p>Im Moment ist Alsa noch nicht per standard verfügbar, sonder muss in dxr3device.c von Hand aktiviert werden.
Am besten nach folgender Zeile ausschau halten:</p>
<blockquote>
<p>audioOut = new cAudioAlsa();</p>
</blockquote>
<p>diese auskommentieren und die Zeile mit cAudioOss() einkommentieren.</p>
<p>Viel Spaß</p>
]]></content:encoded>
    </item>
    <item>
      <title>Google Treasure Hunt 2008</title>
      <link>https://christian-gmeiner.info/2008-11-07-google-treasure-hunt-2008/</link>
      <pubDate>Fri, 07 Nov 2008 10:25:33 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-11-07-google-treasure-hunt-2008/</guid>
      <description>&lt;p&gt;Ich heute zufällig über &lt;a href=&#34;http://planetkde.org/&#34;&gt;http://planetkde.org/&lt;/a&gt; auf den &lt;a href=&#34;http://treasurehunt.appspot.com&#34;&gt;Google Treasure Hunt 2008&lt;/a&gt; aufmerksam geworden und habe es natürlich gleich ausprobiert. Ich habe folgende Aufgabe bearbeitet:&lt;/p&gt;
&lt;p&gt;*Unzip the archive, then process the resulting files to obtain a numeric result. You’ll be taking the sum of lines from files matching a certain description, and multiplying those sums together to obtain a final result. Note that files have many different extensions, like ‘.pdf’ and ‘.js’, but all are plain text files containing a small number of lines of text. *&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Ich heute zufällig über <a href="http://planetkde.org/">http://planetkde.org/</a> auf den <a href="http://treasurehunt.appspot.com">Google Treasure Hunt 2008</a> aufmerksam geworden und habe es natürlich gleich ausprobiert. Ich habe folgende Aufgabe bearbeitet:</p>
<p>*Unzip the archive, then process the resulting files to obtain a numeric result. You’ll be taking the sum of lines from files matching a certain description, and multiplying those sums together to obtain a final result. Note that files have many different extensions, like ‘.pdf’ and ‘.js’, but all are plain text files containing a small number of lines of text. *</p>
<ul>
<li>
<p>Sum of line <strong>4</strong> for all files with path or name containing <strong>BCD</strong> and ending in <strong>.xml</strong>
Sum of line <strong>3</strong> for all files with path or name containing <strong>EFG</strong> and ending in <strong>.xml</strong>
*<em>Hint: If the requested line does not exist, do not increment the sum.</em></p>
</li>
<li>
<p>Multiply all the above sums together and enter the product below.
*<em>(Note: Answer must be an exact, decimal representation of the number.)</em></p>
</li>
</ul>
<p>Mit ein wenig Bash-Scripting ist das auch sehr schnell und einfach lösbar. Viel Spaß beim hacken 🙂</p>
]]></content:encoded>
    </item>
    <item>
      <title>Jaja... ich schreib auch wieder mal was</title>
      <link>https://christian-gmeiner.info/2008-10-27-jaja-ich-schreib-auch-wieder-mal-was/</link>
      <pubDate>Mon, 27 Oct 2008 21:08:43 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-10-27-jaja-ich-schreib-auch-wieder-mal-was/</guid>
      <description>&lt;p&gt;Lange lange ist her, dass das letzte mal etwas geschrieben habe, ich bin einfach nicht der Blogger 🙂
Doch in der Zwischenzeit hat sich einiges getan.&lt;/p&gt;
&lt;p&gt;Zum einen hat das nächste Semester des Master-Studiums begonnen und aus diesem Grund habe ich einiges um die Ohren. Angefangen von AVR32 über Simulation und Modellierung bis hin zur IPhone-Programmierung. Doch auch meine Arbeit in der großen Welt des Open-Source ist auch noch da, wenn nicht immer sichtbar. Ich arbeite, wenn ich Zeit finde an allem was mit Dxr3 zu tun hat und sende hier und da ein paar Patches ab. Wenn alles nach meinem Willen geht, sollte der em8300 Treiber irgendwann in den offiziellen Kernel kommen und sich schön in V4l2 integrieren. Doch bis dahin habe ich noch einiges vor mir. Es ist immer wieder schwer, ob ich am Plugin oder am Treiber weiter arbeiten soll, doch das Plugin muss endlich mal raus. Wäre doch schade um die viele Arbeit.. tja.. bald ist wieder mal Wochenende und evt kann ich dann wieder hacken.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Lange lange ist her, dass das letzte mal etwas geschrieben habe, ich bin einfach nicht der Blogger 🙂
Doch in der Zwischenzeit hat sich einiges getan.</p>
<p>Zum einen hat das nächste Semester des Master-Studiums begonnen und aus diesem Grund habe ich einiges um die Ohren. Angefangen von AVR32 über Simulation und Modellierung bis hin zur IPhone-Programmierung. Doch auch meine Arbeit in der großen Welt des Open-Source ist auch noch da, wenn nicht immer sichtbar. Ich arbeite, wenn ich Zeit finde an allem was mit Dxr3 zu tun hat und sende hier und da ein paar Patches ab. Wenn alles nach meinem Willen geht, sollte der em8300 Treiber irgendwann in den offiziellen Kernel kommen und sich schön in V4l2 integrieren. Doch bis dahin habe ich noch einiges vor mir. Es ist immer wieder schwer, ob ich am Plugin oder am Treiber weiter arbeiten soll, doch das Plugin muss endlich mal raus. Wäre doch schade um die viele Arbeit.. tja.. bald ist wieder mal Wochenende und evt kann ich dann wieder hacken.</p>
<p>Musikalisch gesehn ist mein Leben auch abwechslungsreich geworden und ich kämpfe immer noch mit den gleichen Problemen. Wie zum Teufel kann ich all meine kreative Engerie gut auf der Gitarre umsetzten und mal ein paar neue Songs meinen Bandmembers zeigen. Ich habe einfach zu viele gute Riffs und Parts im Kopf, sodass ich das Problem habe nicht alle in einen Song packen zu können. Tja.. thats live.</p>
]]></content:encoded>
    </item>
    <item>
      <title>SpuEncoder</title>
      <link>https://christian-gmeiner.info/2008-07-31-spuencoder/</link>
      <pubDate>Thu, 31 Jul 2008 17:22:35 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-07-31-spuencoder/</guid>
      <description>&lt;p&gt;Endlich ist es geschafft… ein 4Fraben Osd wird mit dem neuen OSD Code des Dxr3-Plugins angezeigt. Der
verwendete Source ist noch recht voll mit Debug-Stuff und ist auch noch vom Softwaredesign schlecht.
Das möchte ich aber in den kommenden Tagen ändern. Das neue OSD wird auf alle Fälle besser als das alte.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Endlich ist es geschafft… ein 4Fraben Osd wird mit dem neuen OSD Code des Dxr3-Plugins angezeigt. Der
verwendete Source ist noch recht voll mit Debug-Stuff und ist auch noch vom Softwaredesign schlecht.
Das möchte ich aber in den kommenden Tagen ändern. Das neue OSD wird auf alle Fälle besser als das alte.</p>
]]></content:encoded>
    </item>
    <item>
      <title>0x00 und andere Dinge</title>
      <link>https://christian-gmeiner.info/2008-07-25-0x00-und-andere-dinge/</link>
      <pubDate>Fri, 25 Jul 2008 16:24:21 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-07-25-0x00-und-andere-dinge/</guid>
      <description>&lt;p&gt;Leider bin ich schon lange nicht mehr dazu gekommen um ein wenig was zu schreiben. Doch nun endlich
ist dieser Moment gekommen 🙂&lt;/p&gt;
&lt;p&gt;Es sind Ferien und man hat hin und wieder Zeit ein wenig was zu programmieren… das Dxr3-Plugin ist fast so weit, dass das OSD funktioniert. Ich habe das OSD-Bitmap mit rle encoded, habe das OSD in Regionen zu max 4 Farben aufgeteilt und kenne auch schon das DVD Subtitle Format recht gut, doch
es ist einfach noch nichts zu sehen… entweder habe ich noch was vergessen oder das erstellte Paket ist $%@%.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Leider bin ich schon lange nicht mehr dazu gekommen um ein wenig was zu schreiben. Doch nun endlich
ist dieser Moment gekommen 🙂</p>
<p>Es sind Ferien und man hat hin und wieder Zeit ein wenig was zu programmieren… das Dxr3-Plugin ist fast so weit, dass das OSD funktioniert. Ich habe das OSD-Bitmap mit rle encoded, habe das OSD in Regionen zu max 4 Farben aufgeteilt und kenne auch schon das DVD Subtitle Format recht gut, doch
es ist einfach noch nichts zu sehen… entweder habe ich noch was vergessen oder das erstellte Paket ist $%@%.</p>
<p>Bis in 4-5 Tagen sollte dann endlich alles so weit sein, dass ich die erste Alpha der 0.3 er Serie announcen werde.</p>
<p>/me geht jetzt mal an die frische Luft</p>
]]></content:encoded>
    </item>
    <item>
      <title>sound.c und die audiohw api</title>
      <link>https://christian-gmeiner.info/2008-05-15-soundc-und-die-audiohw-api/</link>
      <pubDate>Thu, 15 May 2008 00:37:55 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-05-15-soundc-und-die-audiohw-api/</guid>
      <description>&lt;p&gt;In den letzten Tagen und Wochen war ich recht fleißig und habe weiter an der audiohw API gearbeitet. Mittlerweile ist es mir
gelungen die ifdef-hell ein wenig zu säubern und den Code dadurch wesentlich übersichtlicher zu machen.
In den nächsten Wochen möchte ich gerne folgende Punkte erledigen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prüfen ob &lt;em&gt;audio_is_initialized&lt;/em&gt; überhaupt benötigt wird&lt;/li&gt;
&lt;li&gt;Eine elegante Lösung für &lt;em&gt;set_prescaled_volume&lt;/em&gt; finden (audiohw_set_volume(l, r))&lt;/li&gt;
&lt;li&gt;Einige Sainty-Checks einbauen, ob eine bestimmte AUDIOHW_CAPS Kombination ok ist&lt;/li&gt;
&lt;li&gt;&lt;em&gt;sound_val2phys&lt;/em&gt; in die Audio-Codec Treiber auslagern&lt;/li&gt;
&lt;li&gt;Für die cutoff Funktionen eigene CAPS definieren und verwenden&lt;/li&gt;
&lt;li&gt;Support für 1.5 DB Schritte verbessern&lt;/li&gt;
&lt;li&gt;&lt;em&gt;sound_set_loudness&lt;/em&gt; und Co in den mas35xx Treiber verschieben&lt;/li&gt;
&lt;li&gt;Den DSP für den Simulator verwenden&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Es ist zwar eine lange Liste, doch ich bin nicht unter Zeitdruck 😉&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In den letzten Tagen und Wochen war ich recht fleißig und habe weiter an der audiohw API gearbeitet. Mittlerweile ist es mir
gelungen die ifdef-hell ein wenig zu säubern und den Code dadurch wesentlich übersichtlicher zu machen.
In den nächsten Wochen möchte ich gerne folgende Punkte erledigen:</p>
<ul>
<li>Prüfen ob <em>audio_is_initialized</em> überhaupt benötigt wird</li>
<li>Eine elegante Lösung für <em>set_prescaled_volume</em> finden (audiohw_set_volume(l, r))</li>
<li>Einige Sainty-Checks einbauen, ob eine bestimmte AUDIOHW_CAPS Kombination ok ist</li>
<li><em>sound_val2phys</em> in die Audio-Codec Treiber auslagern</li>
<li>Für die cutoff Funktionen eigene CAPS definieren und verwenden</li>
<li>Support für 1.5 DB Schritte verbessern</li>
<li><em>sound_set_loudness</em> und Co in den mas35xx Treiber verschieben</li>
<li>Den DSP für den Simulator verwenden</li>
</ul>
<p>Es ist zwar eine lange Liste, doch ich bin nicht unter Zeitdruck 😉</p>
]]></content:encoded>
    </item>
    <item>
      <title>Audio device: nVidia Corporation MCP61 High Definition Audio (rev a2)</title>
      <link>https://christian-gmeiner.info/2008-05-06-audio-device-nvidia-corporation-mcp61-high-definition-audio-rev-a2/</link>
      <pubDate>Tue, 06 May 2008 09:50:23 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-05-06-audio-device-nvidia-corporation-mcp61-high-definition-audio-rev-a2/</guid>
      <description>&lt;p&gt;Ich hatte gerade das Problem, dass die MCP61 rev a2 keinen Ton von sich gab. Es handelt sich dabei um ein &lt;strong&gt;Biostar NF61S-M2A&lt;/strong&gt; Mainboard. Um nun die Onboard Soundkarte zur Kooperation zu bewegen, muss man einfach den &lt;strong&gt;Intel HDA&lt;/strong&gt; Treiber verwenden und diese Zeilen in die &lt;strong&gt;/etc/modprobe.conf&lt;/strong&gt; einfügen:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;options snd-hda-intel enable=1 index=0
alias snd-card-0 snd-hda-intel
options snd-hda-intel model=6stack&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Happy Hacking&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Ich hatte gerade das Problem, dass die MCP61 rev a2 keinen Ton von sich gab. Es handelt sich dabei um ein <strong>Biostar NF61S-M2A</strong> Mainboard. Um nun die Onboard Soundkarte zur Kooperation zu bewegen, muss man einfach den <strong>Intel HDA</strong> Treiber verwenden und diese Zeilen in die <strong>/etc/modprobe.conf</strong> einfügen:</p>
<p><em>options snd-hda-intel enable=1 index=0
alias snd-card-0 snd-hda-intel
options snd-hda-intel model=6stack</em></p>
<p>Happy Hacking</p>
]]></content:encoded>
    </item>
    <item>
      <title>OpenRC</title>
      <link>https://christian-gmeiner.info/2008-04-15-openrc/</link>
      <pubDate>Tue, 15 Apr 2008 13:51:13 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-04-15-openrc/</guid>
      <description>&lt;p&gt;Nachdem ich nun meinen Arbeitsrechner neu aufgesetzt habe, dachte ich mir, dass gleich auch noch OpenRC probieren könnte. Mit Hilfe des &lt;a href=&#34;http://www.gentoo.org/doc/en/openrc-migration.xml&#34;&gt;Migration Guide&lt;/a&gt; verlief die Umstellung ohne Probleme und der erste Boot mit OpenRC wurde ausgeführt. Und ich bin sehr erstaunt wie einfach alles ging und das gute an der ganzen Sache… das System startet schneller 🙂&lt;/p&gt;
&lt;p&gt;Nachdem mein Arbeitsrechner nun wieder online ist, werde ich weiter an meinen Projekten arbeiten und hin und wider mal blogen.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Nachdem ich nun meinen Arbeitsrechner neu aufgesetzt habe, dachte ich mir, dass gleich auch noch OpenRC probieren könnte. Mit Hilfe des <a href="http://www.gentoo.org/doc/en/openrc-migration.xml">Migration Guide</a> verlief die Umstellung ohne Probleme und der erste Boot mit OpenRC wurde ausgeführt. Und ich bin sehr erstaunt wie einfach alles ging und das gute an der ganzen Sache… das System startet schneller 🙂</p>
<p>Nachdem mein Arbeitsrechner nun wieder online ist, werde ich weiter an meinen Projekten arbeiten und hin und wider mal blogen.</p>
]]></content:encoded>
    </item>
    <item>
      <title>vdr -h</title>
      <link>https://christian-gmeiner.info/2008-03-29-vdr-h/</link>
      <pubDate>Sat, 29 Mar 2008 16:55:10 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-03-29-vdr-h/</guid>
      <description>&lt;p&gt;Usage: vdr [OPTIONS]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;…&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Plugins: vdr -P”name [OPTIONS]”&lt;/p&gt;
&lt;p&gt;dxr3 (0.3.0_rc1) – em8300 based output device&lt;/p&gt;
&lt;p&gt;-v {pal/ntsc}                –videosystem {pal/ntsc}                 video system to use
default: pal&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Usage: vdr [OPTIONS]</p>
<p><strong>…</strong></p>
<p>Plugins: vdr -P”name [OPTIONS]”</p>
<p>dxr3 (0.3.0_rc1) – em8300 based output device</p>
<p>-v {pal/ntsc}                –videosystem {pal/ntsc}                 video system to use
default: pal</p>
]]></content:encoded>
    </item>
    <item>
      <title>dxr3-plugin 0.3.0 progress</title>
      <link>https://christian-gmeiner.info/2008-03-28-dxr3-plugin-030-progress/</link>
      <pubDate>Fri, 28 Mar 2008 21:59:25 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-03-28-dxr3-plugin-030-progress/</guid>
      <description>&lt;p&gt;Hallo zusammen,&lt;/p&gt;
&lt;p&gt;habe heute ein wenig Zeit gefunden, und habe nun einen Lippen-Synchronen Ton mit passendem Bild 🙂
Leider ist der A/V-Sync Code noch nicht sehr ausgereift und deswegen geht beim Umschalten entweder Bild
oder Ton verloren. Das ‘Problem’ sollte ich über das Wochenende gefixt haben und dann kann ich wieder
einen Punkt aus meiner ToDo streichen.&lt;/p&gt;
&lt;p&gt;Als nächstes werde ich entweder das OSD angehen, oder eine Infrastruktur entwickeln, damit der &lt;em&gt;GrabImage&lt;/em&gt;-API
Aufruf funktioniert bzw das Spektrum-Analyser PCM-Daten vom Plugin bekommt.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Hallo zusammen,</p>
<p>habe heute ein wenig Zeit gefunden, und habe nun einen Lippen-Synchronen Ton mit passendem Bild 🙂
Leider ist der A/V-Sync Code noch nicht sehr ausgereift und deswegen geht beim Umschalten entweder Bild
oder Ton verloren. Das ‘Problem’ sollte ich über das Wochenende gefixt haben und dann kann ich wieder
einen Punkt aus meiner ToDo streichen.</p>
<p>Als nächstes werde ich entweder das OSD angehen, oder eine Infrastruktur entwickeln, damit der <em>GrabImage</em>-API
Aufruf funktioniert bzw das Spektrum-Analyser PCM-Daten vom Plugin bekommt.</p>
<p>Ein Valgrind-Test könnte evt auch nicht schaden und ja.. ein das Plugin crasht beim beenden des VDR’s noch.. wird noch ein
wenig dauern, bis ich Tester brauche und meine Quellen in den SVN auf sourceforge hochladen werde.</p>
<p>Stay tuned</p>
]]></content:encoded>
    </item>
    <item>
      <title>A/V Syncronization</title>
      <link>https://christian-gmeiner.info/2008-03-05-av-syncronization/</link>
      <pubDate>Wed, 05 Mar 2008 03:11:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-03-05-av-syncronization/</guid>
      <description>&lt;p&gt;Mittlerweile läuft meine Version des Dxr3 Plugins recht gut. Es gibt noch ein paar Probleme mit dem A/V Sync. Im Moment arbeite ich an einem neuen OSD und SpuEncoder Teil, bei dem ich schon einige Fortschritte gemacht habe. Zum einen funktioniert die RLE
Kodierung der SPU-Pixelwerte und das mit Hilfe von std::bitset&amp;lt;&amp;gt; und zum anderen habe ich dsa Prinzip hinter der Funktionsweise des
OSD’s komplett verstanden.&lt;/p&gt;
&lt;p&gt;Nachdem A/V Sync gefixt ist und das OSD funktioniert habe ich folgendes noch auf meiner Liste (ausschnitt. nicht sortiert nach Prio)&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Mittlerweile läuft meine Version des Dxr3 Plugins recht gut. Es gibt noch ein paar Probleme mit dem A/V Sync. Im Moment arbeite ich an einem neuen OSD und SpuEncoder Teil, bei dem ich schon einige Fortschritte gemacht habe. Zum einen funktioniert die RLE
Kodierung der SPU-Pixelwerte und das mit Hilfe von std::bitset&lt;&gt; und zum anderen habe ich dsa Prinzip hinter der Funktionsweise des
OSD’s komplett verstanden.</p>
<p>Nachdem A/V Sync gefixt ist und das OSD funktioniert habe ich folgendes noch auf meiner Liste (ausschnitt. nicht sortiert nach Prio)</p>
<ul>
<li>Frabwerte mittels OSD einstellen</li>
<li>ImageGrab –&gt; irgendwann soll mein Atmo auch gehen</li>
<li>PCM-Source für das Spectrum-Analyzer Plugin</li>
<li>i18n</li>
</ul>
<p>Ich hoffe ich finde die nächsten Tage viel Zeit für dieses Projekt…</p>
]]></content:encoded>
    </item>
    <item>
      <title>Dxr3-Plugin 0.3.0</title>
      <link>https://christian-gmeiner.info/2008-02-26-dxr3-plugin-030/</link>
      <pubDate>Tue, 26 Feb 2008 15:49:14 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-02-26-dxr3-plugin-030/</guid>
      <description>&lt;p&gt;Nachdem ich schon seit eingier Zeit an einer neuen Version des VDR Plugins abreite, habe ich die letzten Tage sehr viel Zeit zum
programmieren gefunden und habe  das Dxr3  Plugin komplett neu geschrieben. Im Moment arbeite ich am A/V sync, und sonst noch
ein paar Goodies.&lt;/p&gt;
&lt;p&gt;Hier mal ein kleiner Vorgeschmack:&lt;/p&gt;
&lt;p&gt;Feb 26 14:44:59 vdr vdr: [24405] initializing plugin: dxr3 (0.3.0_rc1): TODO
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-decoder] using avcodec/ffmpeg version 3352580 build 3352580
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-interface] ready…
Feb 26 14:44:59 vdr vdr: [24405] ERROR: /dev/em8300_ma-0: Datei oder Verzeichnis nicht gefunden
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-output-audio] using alsa driver
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-interface] ioctl 1074021127 on 0 with result 0
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-interface] ioctl 1074545410 on 0 with result 0
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-interface] ioctl 1074021126 on 0 with result 0
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-interface] ioctl 1074021137 on 0 with result 0
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-interface] ioctl 1074021136 on 0 with result 0
Feb 26 14:44:59 vdr vdr: [24405] initializing plugin: live (0.1.0): Live Interactive VDR Environment
Feb 26 14:44:59 vdr vdr: [24405] setting primary device to 2
Feb 26 14:44:59 vdr vdr: [24412] Audio-Output Thread (dxr3) thread started (pid=24405, tid=24412)
Feb 26 14:44:59 vdr vdr: [24413] Video-Output Thread (dxr3) thread started (pid=24405, tid=24413)
Feb 26 14:44:59 vdr vdr: [24405] assuming manual start of VDR
Feb 26 14:44:59 vdr vdr: [24405] SVDRP listening on port 2001
Feb 26 14:44:59 vdr vdr: [24405] setting current skin to “sttng”
Feb 26 14:44:59 vdr vdr: [24405] loading /etc/vdr//themes/sttng-default.theme
Feb 26 14:44:59 vdr vdr: [24405] starting plugin: dxr3
Feb 26 14:44:59 vdr vdr: [24405] starting plugin: live
Feb 26 14:44:59 vdr vdr: [24405] LIVE: initial file cache has 82 entries and needs 300358 bytes of data!
Feb 26 14:44:59 vdr vdr: [24416] KBD remote control thread started (pid=24405, tid=24416)
Feb 26 14:44:59 vdr vdr: [24405] remote control KBD – learning keys
Feb 26 14:44:59 vdr vdr: [24405] ERROR: no OSD provider available – using dummy OSD!
Feb 26 14:45:01 vdr vdr: [24409] CAM 1: no module present
Feb 26 14:45:09 vdr vdr: [24405] switching to channel 2
Feb 26 14:45:09 vdr vdr: [24424] transfer thread started (pid=24405, tid=24424)
Feb 26 14:45:09 vdr vdr: [24425] receiver on device 1 thread started (pid=24405, tid=24425)
Feb 26 14:45:09 vdr vdr: [24426] TS buffer on device 1 thread started (pid=24405, tid=24426)
Feb 26 14:45:09 vdr vdr: [24405] ERROR: no OSD provider available – using dummy OSD!
Feb 26 14:45:09 vdr vdr: [24405] live reloading timers
Feb 26 14:45:10 vdr vdr: [24413] [dxr3-output] starting
Feb 26 14:45:10 vdr vdr: [24424] setting audio track to 1 (0)
Feb 26 14:45:10 vdr vdr: [24424] [dxr3-audio-alsa] switching to analog audio
Feb 26 14:45:10 vdr vdr: [24412] [dxr3-output] starting
Feb 26 14:45:10 vdr vdr: [24412] [dxr-audio-alsa] changing samplerate to 48000 (old 0)
Feb 26 14:45:10 vdr vdr: [24412] [dxr-audio-alsa] changing num of channels to 2 (old 0)&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Nachdem ich schon seit eingier Zeit an einer neuen Version des VDR Plugins abreite, habe ich die letzten Tage sehr viel Zeit zum
programmieren gefunden und habe  das Dxr3  Plugin komplett neu geschrieben. Im Moment arbeite ich am A/V sync, und sonst noch
ein paar Goodies.</p>
<p>Hier mal ein kleiner Vorgeschmack:</p>
<p>Feb 26 14:44:59 vdr vdr: [24405] initializing plugin: dxr3 (0.3.0_rc1): TODO
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-decoder] using avcodec/ffmpeg version 3352580 build 3352580
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-interface] ready…
Feb 26 14:44:59 vdr vdr: [24405] ERROR: /dev/em8300_ma-0: Datei oder Verzeichnis nicht gefunden
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-output-audio] using alsa driver
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-interface] ioctl 1074021127 on 0 with result 0
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-interface] ioctl 1074545410 on 0 with result 0
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-interface] ioctl 1074021126 on 0 with result 0
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-interface] ioctl 1074021137 on 0 with result 0
Feb 26 14:44:59 vdr vdr: [24405] [dxr3-interface] ioctl 1074021136 on 0 with result 0
Feb 26 14:44:59 vdr vdr: [24405] initializing plugin: live (0.1.0): Live Interactive VDR Environment
Feb 26 14:44:59 vdr vdr: [24405] setting primary device to 2
Feb 26 14:44:59 vdr vdr: [24412] Audio-Output Thread (dxr3) thread started (pid=24405, tid=24412)
Feb 26 14:44:59 vdr vdr: [24413] Video-Output Thread (dxr3) thread started (pid=24405, tid=24413)
Feb 26 14:44:59 vdr vdr: [24405] assuming manual start of VDR
Feb 26 14:44:59 vdr vdr: [24405] SVDRP listening on port 2001
Feb 26 14:44:59 vdr vdr: [24405] setting current skin to “sttng”
Feb 26 14:44:59 vdr vdr: [24405] loading /etc/vdr//themes/sttng-default.theme
Feb 26 14:44:59 vdr vdr: [24405] starting plugin: dxr3
Feb 26 14:44:59 vdr vdr: [24405] starting plugin: live
Feb 26 14:44:59 vdr vdr: [24405] LIVE: initial file cache has 82 entries and needs 300358 bytes of data!
Feb 26 14:44:59 vdr vdr: [24416] KBD remote control thread started (pid=24405, tid=24416)
Feb 26 14:44:59 vdr vdr: [24405] remote control KBD – learning keys
Feb 26 14:44:59 vdr vdr: [24405] ERROR: no OSD provider available – using dummy OSD!
Feb 26 14:45:01 vdr vdr: [24409] CAM 1: no module present
Feb 26 14:45:09 vdr vdr: [24405] switching to channel 2
Feb 26 14:45:09 vdr vdr: [24424] transfer thread started (pid=24405, tid=24424)
Feb 26 14:45:09 vdr vdr: [24425] receiver on device 1 thread started (pid=24405, tid=24425)
Feb 26 14:45:09 vdr vdr: [24426] TS buffer on device 1 thread started (pid=24405, tid=24426)
Feb 26 14:45:09 vdr vdr: [24405] ERROR: no OSD provider available – using dummy OSD!
Feb 26 14:45:09 vdr vdr: [24405] live reloading timers
Feb 26 14:45:10 vdr vdr: [24413] [dxr3-output] starting
Feb 26 14:45:10 vdr vdr: [24424] setting audio track to 1 (0)
Feb 26 14:45:10 vdr vdr: [24424] [dxr3-audio-alsa] switching to analog audio
Feb 26 14:45:10 vdr vdr: [24412] [dxr3-output] starting
Feb 26 14:45:10 vdr vdr: [24412] [dxr-audio-alsa] changing samplerate to 48000 (old 0)
Feb 26 14:45:10 vdr vdr: [24412] [dxr-audio-alsa] changing num of channels to 2 (old 0)</p>
]]></content:encoded>
    </item>
    <item>
      <title>AudioHw Unification</title>
      <link>https://christian-gmeiner.info/2008-02-14-audiohw-unification/</link>
      <pubDate>Thu, 14 Feb 2008 15:40:09 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-02-14-audiohw-unification/</guid>
      <description>&lt;p&gt;Im Moment nutze ich meine Freizeit um die AudioHw-Schicht in Rockbox ein wenig aufzuräumen und v.a. firmware/sound.c aufzuräumen und zu vereinfachen.&lt;/p&gt;
&lt;p&gt;Hier einmal die großen Ziele von diesem Projekt:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Eigener Audio-Treiber für die zwei Mas-Codec&lt;/li&gt;
&lt;li&gt;Einfache Möglichkeit um für ein Codec zu definieren was es alles in Hardware machen kann
Z.b.: Bass, Prescaler,…&lt;/li&gt;
&lt;li&gt;Einheitliches Interface um die Lautstärke zu regulieren –&amp;gt; audiohw_set_volume(l, r)&lt;/li&gt;
&lt;li&gt;Preinit/Postinit aufräume&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Eine sehr große Liste, doch sollte machbar sein. Ich freue mich schon auf ein paar Stunden Programmierarbeit.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Im Moment nutze ich meine Freizeit um die AudioHw-Schicht in Rockbox ein wenig aufzuräumen und v.a. firmware/sound.c aufzuräumen und zu vereinfachen.</p>
<p>Hier einmal die großen Ziele von diesem Projekt:</p>
<ul>
<li>Eigener Audio-Treiber für die zwei Mas-Codec</li>
<li>Einfache Möglichkeit um für ein Codec zu definieren was es alles in Hardware machen kann
Z.b.: Bass, Prescaler,…</li>
<li>Einheitliches Interface um die Lautstärke zu regulieren –&gt; audiohw_set_volume(l, r)</li>
<li>Preinit/Postinit aufräume</li>
</ul>
<p>Eine sehr große Liste, doch sollte machbar sein. Ich freue mich schon auf ein paar Stunden Programmierarbeit.</p>
]]></content:encoded>
    </item>
    <item>
      <title>checking for XML::Parser... configure: error: XML::Parser perl module...</title>
      <link>https://christian-gmeiner.info/2008-02-14-checking-for-xmlparser-configure-error-xmlparser-perl-module/</link>
      <pubDate>Thu, 14 Feb 2008 12:21:14 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-02-14-checking-for-xmlparser-configure-error-xmlparser-perl-module/</guid>
      <description>&lt;p&gt;is equired for intltool.&lt;/p&gt;
&lt;p&gt;Dieser Fehler bekam ich bei einem Update des NetworkManager’s unter Gentoo. Scheinbar ist hängt dies mit Perl, intltool und dem xml parser zusammen. Für mehr Informationen einfach einen Blick auf &lt;a href=&#34;https://bugs.gentoo.org/show_bug.cgi?id=41124&#34; title=&#34;Gentoo Bugs&#34;&gt;https://bugs.gentoo.org/show_bug.cgi?id=41124&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Und hier nun die sehr einfache Lösung – works for me(tm)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;emerge  XML-Parser networkmanger&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Happy Hacking..&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>is equired for intltool.</p>
<p>Dieser Fehler bekam ich bei einem Update des NetworkManager’s unter Gentoo. Scheinbar ist hängt dies mit Perl, intltool und dem xml parser zusammen. Für mehr Informationen einfach einen Blick auf <a href="https://bugs.gentoo.org/show_bug.cgi?id=41124" title="Gentoo Bugs">https://bugs.gentoo.org/show_bug.cgi?id=41124</a></p>
<p>Und hier nun die sehr einfache Lösung – works for me(tm)</p>
<p><em>emerge  XML-Parser networkmanger</em></p>
<p>Happy Hacking..</p>
]]></content:encoded>
    </item>
    <item>
      <title>Star Wars...</title>
      <link>https://christian-gmeiner.info/2008-01-16-star-wars/</link>
      <pubDate>Wed, 16 Jan 2008 14:10:55 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-01-16-star-wars/</guid>
      <description>&lt;p&gt;Welcher Star Wars-Fan und Geek wollte nich nie Star Wars ala Ascii-Art sehen?!
So einfach funktioniert es: telnet towel.blinkenlights.nl&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Welcher Star Wars-Fan und Geek wollte nich nie Star Wars ala Ascii-Art sehen?!
So einfach funktioniert es: telnet towel.blinkenlights.nl</p>
]]></content:encoded>
    </item>
    <item>
      <title>Ein schöner Tag...</title>
      <link>https://christian-gmeiner.info/2008-01-11-ein-schoner-tag/</link>
      <pubDate>Fri, 11 Jan 2008 22:32:44 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-01-11-ein-schoner-tag/</guid>
      <description>&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://kde.org/img/kde40.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Ich spiele im Moment mit dem Gedanken bei der Entwicklung von KDE aktiv mitzuwirken. Wäre auf jeden Fall keine schlechte Idee, da ein so grosses
Projekt nie genug fähige  Programmierer,  Artiests, … haben kann.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>…</p>
<p><img loading="lazy" src="http://kde.org/img/kde40.png"></p>
<p>Ich spiele im Moment mit dem Gedanken bei der Entwicklung von KDE aktiv mitzuwirken. Wäre auf jeden Fall keine schlechte Idee, da ein so grosses
Projekt nie genug fähige  Programmierer,  Artiests, … haben kann.</p>
]]></content:encoded>
    </item>
    <item>
      <title>M-Audio Keystation 49e USB midi-keyboard</title>
      <link>https://christian-gmeiner.info/2008-01-07-m-audio-keystation-49e-usb-midi-keyboard/</link>
      <pubDate>Mon, 07 Jan 2008 13:01:11 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2008-01-07-m-audio-keystation-49e-usb-midi-keyboard/</guid>
      <description>&lt;p&gt;Wie ich auf der Seite von linuxdriverproject sehen kann, schein das M-Audio 49e midi-keyboard und Linux nicht zu funktionieren. Dem kann ich nicht zustimmen und werde hier ein kleines HowTo posten.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Als ersten einmal die Ausgabe von &lt;em&gt;lsusb -vvv&lt;/em&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bus 002 Device 012: ID 0a4d:0090 Evolution Electronics, Ltd
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0a4d Evolution Electronics, Ltd
idProduct 0x0090
bcdDevice 1.13
iManufacturer 1 Evolution Electronics Ltd.
iProduct 2 USB Keystation 49e
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 101
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 3 Audio Class
bmAttributes 0xc0
Self Powered
MaxPower 0mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 9
bInCollection 1
baInterfaceNr( 0) 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 1 Audio
bInterfaceSubClass 3 MIDI Streaming
bInterfaceProtocol 0
iInterface 0
MIDIStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 65
MIDIStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (MIDI_IN_JACK)
bJackType 1 Embedded
bJackID 1
iJack 0
MIDIStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (MIDI_IN_JACK)
bJackType 2 External
bJackID 2
iJack 0
MIDIStreaming Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (MIDI_OUT_JACK)
bJackType 1 Embedded
bJackID 3
bNrInputPins 1
baSourceID( 0) 2
BaSourcePin( 0) 1
iJack 0
MIDIStreaming Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (MIDI_OUT_JACK)
bJackType 2 External
bJackID 4
bNrInputPins 1
baSourceID( 0) 1
BaSourcePin( 0) 1
iJack 0
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
bRefresh 0
bSynchAddress 0
MIDIStreaming Endpoint Descriptor:
bLength 5
bDescriptorType 37
bDescriptorSubtype 1 (GENERAL)
bNumEmbMIDIJack 1
baAssocJackID( 0) 3
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
bRefresh 0
bSynchAddress 0
MIDIStreaming Endpoint Descriptor:
bLength 5
bDescriptorType 37
bDescriptorSubtype 1 (GENERAL)
bNumEmbMIDIJack 1
baAssocJackID( 0) 1
Device Status: 0x0000
(Bus Powered)&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Wie ich auf der Seite von linuxdriverproject sehen kann, schein das M-Audio 49e midi-keyboard und Linux nicht zu funktionieren. Dem kann ich nicht zustimmen und werde hier ein kleines HowTo posten.</p>
<ul>
<li>Als ersten einmal die Ausgabe von <em>lsusb -vvv</em>:</li>
</ul>
<p>Bus 002 Device 012: ID 0a4d:0090 Evolution Electronics, Ltd
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0a4d Evolution Electronics, Ltd
idProduct 0x0090
bcdDevice 1.13
iManufacturer 1 Evolution Electronics Ltd.
iProduct 2 USB Keystation 49e
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 101
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 3 Audio Class
bmAttributes 0xc0
Self Powered
MaxPower 0mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 9
bInCollection 1
baInterfaceNr( 0) 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 1 Audio
bInterfaceSubClass 3 MIDI Streaming
bInterfaceProtocol 0
iInterface 0
MIDIStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 65
MIDIStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (MIDI_IN_JACK)
bJackType 1 Embedded
bJackID 1
iJack 0
MIDIStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 2 (MIDI_IN_JACK)
bJackType 2 External
bJackID 2
iJack 0
MIDIStreaming Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (MIDI_OUT_JACK)
bJackType 1 Embedded
bJackID 3
bNrInputPins 1
baSourceID( 0) 2
BaSourcePin( 0) 1
iJack 0
MIDIStreaming Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (MIDI_OUT_JACK)
bJackType 2 External
bJackID 4
bNrInputPins 1
baSourceID( 0) 1
BaSourcePin( 0) 1
iJack 0
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
bRefresh 0
bSynchAddress 0
MIDIStreaming Endpoint Descriptor:
bLength 5
bDescriptorType 37
bDescriptorSubtype 1 (GENERAL)
bNumEmbMIDIJack 1
baAssocJackID( 0) 3
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
bRefresh 0
bSynchAddress 0
MIDIStreaming Endpoint Descriptor:
bLength 5
bDescriptorType 37
bDescriptorSubtype 1 (GENERAL)
bNumEmbMIDIJack 1
baAssocJackID( 0) 1
Device Status: 0x0000
(Bus Powered)</p>
<ul>
<li>Nun einmal die Ausgabe von <em>dmesg</em> beim Einstecken des Keyboards:</li>
</ul>
<p>usb 2-6: new full speed USB device using ohci_hcd and address 14
ohci_hcd 0000:00:0a.0: GetStatus roothub.portstatus [5] = 0x00100103 PRSC PPS PES CCS
usb 2-6: skipped 1 descriptor after interface
usb 2-6: skipped 5 descriptors after interface
usb 2-6: skipped 1 descriptor after endpoint
usb 2-6: skipped 1 descriptor after endpoint
usb 2-6: default language 0x0409
usb 2-6: new device strings: Mfr=1, Product=2, SerialNumber=0
usb 2-6: Product: USB Keystation 49e
usb 2-6: Manufacturer: Evolution Electronics Ltd.
usb 2-6: uevent
usb 2-6: usb_probe_device
usb 2-6: configuration #1 chosen from 1 choice
usb 2-6: adding 2-6:1.0 (config #1, interface 0)
usb 2-6:1.0: uevent
usb 2-6:1.0: uevent
snd-usb-audio 2-6:1.0: usb_probe_interface
snd-usb-audio 2-6:1.0: usb_probe_interface – got id
usb 2-6: adding 2-6:1.1 (config #1, interface 1)
usb 2-6:1.1: uevent
usb 2-6:1.1: uevent
drivers/usb/core/inode.c: creating file ‘014’
hub 2-0:1.0: state 7 ports 10 chg 0000 evt 0040</p>
<ul>
<li>Die Konfiguration des Kernels</li>
</ul>
<p>Ist eigentlich sehr sehr einfach. Man muss nur **Device Drivers/Sound/Advanced Linux Sound Architecture/USB Devices/USB Audio/MIDI driver **als Modul oder fest in den Kernel kompilieren.</p>
<p>Schon kann man mit dem Midi-Keyboard in wine und nativ arbeiten, z.B. mit rosegarden.</p>
<p><a href="javascript:void(0)" title="Rosgarden und das 49e midi-keyboard"></a> <a href="javascript:void(0)" title="Rosgarden und das 49e midi-keyboard"></a> <a href="http://www.christian-gmeiner.info/wordpress/wp-content/uploads/2008/01/rosgarden.png" title="Direct link to file"><img alt="Rosgarden und das 49e midi-keyboard" loading="lazy" src="http://www.christian-gmeiner.info/wordpress/wp-content/uploads/2008/01/rosgarden.thumbnail.png"></a></p>
]]></content:encoded>
    </item>
    <item>
      <title>KDE 4</title>
      <link>https://christian-gmeiner.info/2007-12-11-kde-4/</link>
      <pubDate>Tue, 11 Dec 2007 10:44:31 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2007-12-11-kde-4/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;KDE 4.0 Release Counter&#34; loading=&#34;lazy&#34; src=&#34;http://games.kde.org/new/counter/&#34;&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img alt="KDE 4.0 Release Counter" loading="lazy" src="http://games.kde.org/new/counter/"></p>
]]></content:encoded>
    </item>
    <item>
      <title>Serial over USB</title>
      <link>https://christian-gmeiner.info/2007-11-30-serial-over-usb/</link>
      <pubDate>Fri, 30 Nov 2007 02:22:55 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2007-11-30-serial-over-usb/</guid>
      <description>&lt;p&gt;Nachdem ein neuer Stack meine alten USB-Stack, welcher im Google Summer of Code für &lt;a href=&#34;http://www.rockbox.org&#34;&gt;RockBox&lt;/a&gt; erstellt wurde, durch einen wenig objektorientierten und nicht so generischen USB-Stack ersetzt wurde, habe ich in weniger als 20 Minuten einen serial Treiber geschrieben.  Leider ist der neue Stack noch fertig und es fehlt eine wichtige Funktionalität: Umschalten zwischen verschieden device Treibern zur Laufzeit… bald ist ja Wochenende.&lt;/p&gt;
&lt;p&gt;Revision 15850 rockt 🙂&lt;/p&gt;
&lt;h1 id=&#34;modprobe-usbserial-vendor0x0781-product0x7421-debug1&#34;&gt;modprobe usbserial vendor=0x0781 product=0x7421 debug=1&lt;/h1&gt;
&lt;h1 id=&#34;picocom-devttyusb0&#34;&gt;picocom /dev/ttyUSB0&lt;/h1&gt;</description>
      <content:encoded><![CDATA[<p>Nachdem ein neuer Stack meine alten USB-Stack, welcher im Google Summer of Code für <a href="http://www.rockbox.org">RockBox</a> erstellt wurde, durch einen wenig objektorientierten und nicht so generischen USB-Stack ersetzt wurde, habe ich in weniger als 20 Minuten einen serial Treiber geschrieben.  Leider ist der neue Stack noch fertig und es fehlt eine wichtige Funktionalität: Umschalten zwischen verschieden device Treibern zur Laufzeit… bald ist ja Wochenende.</p>
<p>Revision 15850 rockt 🙂</p>
<h1 id="modprobe-usbserial-vendor0x0781-product0x7421-debug1">modprobe usbserial vendor=0x0781 product=0x7421 debug=1</h1>
<h1 id="picocom-devttyusb0">picocom /dev/ttyUSB0</h1>
]]></content:encoded>
    </item>
    <item>
      <title>EBNF</title>
      <link>https://christian-gmeiner.info/2007-11-28-ebnf/</link>
      <pubDate>Wed, 28 Nov 2007 02:02:27 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2007-11-28-ebnf/</guid>
      <description>&lt;p&gt;Für das Seminar “Konzepte konkreter und abstrakter Maschinen” habe ich einen kleinen &lt;a href=&#34;http://de.wikipedia.org/wiki/Erweiterte_Backus-Naur-Form&#34; title=&#34;EBNF@Wikipedia&#34;&gt;EBNF&lt;/a&gt;-Parser geschrieben, der die Korrektheit der EBNF-Syntax prüft und die Regeln verdeutscht. Der Parser wurde in Java innerhalb von kapp 2 Stunden entwickelt…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;digit = ‘0’|’1’|’2′.
hexdigit = digit|’A’|’B’|’C’|’D’|’E’|’F’.
vorzeichen = ‘-‘|’+’.
zahl = [vorzeichen] hexdigit {hexdigit}.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Wird zu:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;digit = ‘0’ oder ‘1’ oder ‘2’
hexdigit = ‘digit’ oder ‘A’ oder ‘B’ oder ‘C’ oder ‘D’ oder ‘E’ oder ‘F’
vorzeichen = ‘-‘ oder ‘+’
zahl = entweder leer oder gleich ‘vorzeichen’ ‘hexdigit’ keinem, einem, oder mehreren ‘hexdigit’
EBNF check ok&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Für das Seminar “Konzepte konkreter und abstrakter Maschinen” habe ich einen kleinen <a href="http://de.wikipedia.org/wiki/Erweiterte_Backus-Naur-Form" title="EBNF@Wikipedia">EBNF</a>-Parser geschrieben, der die Korrektheit der EBNF-Syntax prüft und die Regeln verdeutscht. Der Parser wurde in Java innerhalb von kapp 2 Stunden entwickelt…</p>
<blockquote>
<p>digit = ‘0’|’1’|’2′.
hexdigit = digit|’A’|’B’|’C’|’D’|’E’|’F’.
vorzeichen = ‘-‘|’+’.
zahl = [vorzeichen] hexdigit {hexdigit}.</p>
</blockquote>
<p>Wird zu:</p>
<blockquote>
<p>digit = ‘0’ oder ‘1’ oder ‘2’
hexdigit = ‘digit’ oder ‘A’ oder ‘B’ oder ‘C’ oder ‘D’ oder ‘E’ oder ‘F’
vorzeichen = ‘-‘ oder ‘+’
zahl = entweder leer oder gleich ‘vorzeichen’ ‘hexdigit’ keinem, einem, oder mehreren ‘hexdigit’
EBNF check ok</p>
</blockquote>
<p>Zweites Beispiel mit Fehler…</p>
<blockquote>
<p>digit = ‘0’|’1’|’2′.
hexdigit = zahl|’A’|’B’|’C’|’D’|’E’|’F’.</p>
</blockquote>
<p>wird zu…</p>
<blockquote>
<p>digit = ‘0’ oder ‘1’ oder ‘2’
hexdigit = EBNF-Error: ‘zahl’ not defined – at line 2</p>
</blockquote>
]]></content:encoded>
    </item>
    <item>
      <title>Icecream.. *lecker*</title>
      <link>https://christian-gmeiner.info/2007-11-01-icecream-lecker/</link>
      <pubDate>Thu, 01 Nov 2007 18:39:50 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2007-11-01-icecream-lecker/</guid>
      <description>&lt;p&gt;Wer &lt;a href=&#34;http://www.gentoo.org&#34; title=&#34;Gentoo Linux&#34;&gt;Gentoo&lt;/a&gt; verwendet oder sehr viel Code compilieren muss, sollte sich Gedanken machen wie man das Compileren beschleunigen könnte. Eine Lösung wäre die Verwendung eines Compile-Clusters. Ich habe mich hierbei für &lt;a href=&#34;http://en.opensuse.org/Icecream&#34; title=&#34;Icecream&#34;&gt;Icecream&lt;/a&gt; entschieden. Wie immer eine kleine Installationsanleitung für Gentoo 🙂&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;h1 id=&#34;emerge-sys-develicecream&#34;&gt;emerge sys-devel/icecream&lt;/h1&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h1 id=&#34;rc-update-add-icecream-default&#34;&gt;rc-update add icecream default&lt;/h1&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;/etc/conf.d/icecream&lt;/em&gt; nach eigenen Wünschen bearbeiten*&lt;/li&gt;
&lt;li&gt;
&lt;h1 id=&#34;etcinitdicecream-start&#34;&gt;/etc/init.d/icecream start&lt;/h1&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Diese Schritte auf allen Gentoo Maschienen durchführen, welche am Compile-Cluster teilhaben sollen.&lt;/p&gt;
&lt;p&gt;Nachdem der Cluster nun einsatzbereit ist, muss nur noch &lt;em&gt;/etc/make.conf&lt;/em&gt; und &lt;strong&gt;PATH&lt;/strong&gt; angepasst werden, damit der Cluster verwendet werden kann.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Wer <a href="http://www.gentoo.org" title="Gentoo Linux">Gentoo</a> verwendet oder sehr viel Code compilieren muss, sollte sich Gedanken machen wie man das Compileren beschleunigen könnte. Eine Lösung wäre die Verwendung eines Compile-Clusters. Ich habe mich hierbei für <a href="http://en.opensuse.org/Icecream" title="Icecream">Icecream</a> entschieden. Wie immer eine kleine Installationsanleitung für Gentoo 🙂</p>
<ul>
<li>
<h1 id="emerge-sys-develicecream">emerge sys-devel/icecream</h1>
</li>
<li>
<h1 id="rc-update-add-icecream-default">rc-update add icecream default</h1>
</li>
<li><em>/etc/conf.d/icecream</em> nach eigenen Wünschen bearbeiten*</li>
<li>
<h1 id="etcinitdicecream-start">/etc/init.d/icecream start</h1>
</li>
</ul>
<p>Diese Schritte auf allen Gentoo Maschienen durchführen, welche am Compile-Cluster teilhaben sollen.</p>
<p>Nachdem der Cluster nun einsatzbereit ist, muss nur noch <em>/etc/make.conf</em> und <strong>PATH</strong> angepasst werden, damit der Cluster verwendet werden kann.</p>
<ul>
<li>
<h1 id="export-pathusrlibiceccbinpath">export PATH=/usr/lib/icecc/bin/:$PATH</h1>
</li>
<li>
<h1 id="prerootpathusrlibiceccbin-in-etcmakeconf-hinzufügen">PREROOTPATH=”/usr/lib/icecc/bin” in <em>/etc/make.conf</em> hinzufügen</h1>
</li>
</ul>
<p>Nun wird bei jedem emerge der Cluster verwendet und auch bei normalen Compile-Aufgaben. Im Moment habe ich einen kleinen Compile-Cluster bestehend aus 3 Gentoo-Rechner…</p>
<p>Happy Hacking…</p>
<ul>
<li>Im Compile-Cluster darf es nur einen Node mit ICECREAM_RUN_SCHEDULER=”yes” geben.</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Schlaf Laptop schlaf...</title>
      <link>https://christian-gmeiner.info/2007-10-28-schlaf-laptop-schlaf/</link>
      <pubDate>Sun, 28 Oct 2007 16:37:14 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2007-10-28-schlaf-laptop-schlaf/</guid>
      <description>&lt;p&gt;Suspend war und ist immer noch ein Knackpunkt von Linux. Doch zum Glück kann ich sagen, dass sich die Situation verbessert hat und nun ist es ohne Suspend2 Patches möglich mit einem aktuellen Kernel 2.6.23 Suspend2Ram und Supend2Disk zu verwendet. Nach einer schnellen Kernelconfig-Änderung und dem hinzufügen von &lt;em&gt;&lt;strong&gt;resume=/dev/hda2&lt;/strong&gt;&lt;/em&gt;zu den Boot-Pararmetern genügten schon um von Kernel-Seite alles bereitzustellen.&lt;/p&gt;
&lt;p&gt;Jetzt fehlt nur noch der Userspace 🙂 Unter Gentoo reicht ein  einfaches ***emerge sys-power/suspend ***und dem Supendieren steht nichts mehr im Weg. Unter KDE ist KPowersave sehr zu empfehlen.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Suspend war und ist immer noch ein Knackpunkt von Linux. Doch zum Glück kann ich sagen, dass sich die Situation verbessert hat und nun ist es ohne Suspend2 Patches möglich mit einem aktuellen Kernel 2.6.23 Suspend2Ram und Supend2Disk zu verwendet. Nach einer schnellen Kernelconfig-Änderung und dem hinzufügen von <em><strong>resume=/dev/hda2</strong></em>zu den Boot-Pararmetern genügten schon um von Kernel-Seite alles bereitzustellen.</p>
<p>Jetzt fehlt nur noch der Userspace 🙂 Unter Gentoo reicht ein  einfaches ***emerge sys-power/suspend ***und dem Supendieren steht nichts mehr im Weg. Unter KDE ist KPowersave sehr zu empfehlen.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Octave 2.9 mit Gentoo</title>
      <link>https://christian-gmeiner.info/2007-10-07-octave-29-mit-gentoo/</link>
      <pubDate>Sun, 07 Oct 2007 19:12:50 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2007-10-07-octave-29-mit-gentoo/</guid>
      <description>&lt;p&gt;Leider ist das offizielle Portage nicht immer up2date (&lt;strong&gt;sci-mathematics/octave-2.1.73-r2&lt;/strong&gt;) und aus diesem Grund hier nun der einfachste Weg zu octave 2.9 unter Gentoo.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;# emerge layman&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;# layman -a science&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;# echo “source /usr/portage/local/layman/make.conf” &amp;raquo; /etc/make.conf&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;# emerge -av octave&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These are the packages that would be merged, in order:&lt;/p&gt;
&lt;p&gt;Calculating dependencies… done!
[ebuild N ] app-admin/eselect-blas-0.1 0 kB
[ebuild N ] sci-mathematics/glpk-4.22 USE=”-doc” 1,385 kB
[ebuild N ] app-admin/eselect-lapack-0.1 0 kB
[ebuild N ] dev-tcltk/expect-5.43.0 USE=”X -doc” 514 kB
[ebuild N ] dev-util/gperf-3.0.3 845 kB
[ebuild N ] sci-libs/blas-reference-20070226 USE=”-debug -doc” 5,208 kB
[ebuild N ] dev-util/dejagnu-1.4.4-r1 USE=”-doc” 1,056 kB
[ebuild N ] virtual/blas-1.0 0 kB [1]
[ebuild N ] sci-libs/lapack-reference-3.1.1-r1 USE=”-debug -doc” 0 kB
[ebuild N ] virtual/lapack-1.0 0 kB [1]
[ebuild N ] &lt;strong&gt;sci-mathematics/octave-2.9.14&lt;/strong&gt; USE=”readline -curl -debug -doc -emacs -hdf5 -zlib” 9,185 kB [1]&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Leider ist das offizielle Portage nicht immer up2date (<strong>sci-mathematics/octave-2.1.73-r2</strong>) und aus diesem Grund hier nun der einfachste Weg zu octave 2.9 unter Gentoo.</p>
<ol>
<li><em># emerge layman</em></li>
<li><em># layman -a science</em></li>
<li><em># echo “source /usr/portage/local/layman/make.conf” &raquo; /etc/make.conf</em></li>
<li><em># emerge -av octave</em></li>
</ol>
<p>These are the packages that would be merged, in order:</p>
<p>Calculating dependencies… done!
[ebuild N ] app-admin/eselect-blas-0.1 0 kB
[ebuild N ] sci-mathematics/glpk-4.22 USE=”-doc” 1,385 kB
[ebuild N ] app-admin/eselect-lapack-0.1 0 kB
[ebuild N ] dev-tcltk/expect-5.43.0 USE=”X -doc” 514 kB
[ebuild N ] dev-util/gperf-3.0.3 845 kB
[ebuild N ] sci-libs/blas-reference-20070226 USE=”-debug -doc” 5,208 kB
[ebuild N ] dev-util/dejagnu-1.4.4-r1 USE=”-doc” 1,056 kB
[ebuild N ] virtual/blas-1.0 0 kB [1]
[ebuild N ] sci-libs/lapack-reference-3.1.1-r1 USE=”-debug -doc” 0 kB
[ebuild N ] virtual/lapack-1.0 0 kB [1]
[ebuild N ] <strong>sci-mathematics/octave-2.9.14</strong> USE=”readline -curl -debug -doc -emacs -hdf5 -zlib” 9,185 kB [1]</p>
<p>Total: 11 packages (11 new), Size of downloads: 18,190 kB
Portage tree and overlays:
[0] /usr/portage
[1] /usr/portage/local/layman/science</p>
<p>Would you like to merge these packages? [Yes/No]</p>
]]></content:encoded>
    </item>
    <item>
      <title>Wine Crosstests erstellen</title>
      <link>https://christian-gmeiner.info/2007-09-26-wine-crosstests-erstellen/</link>
      <pubDate>Wed, 26 Sep 2007 01:02:30 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2007-09-26-wine-crosstests-erstellen/</guid>
      <description>&lt;p&gt;Nachdem ich im Moment ein paar kleine Patches für Wine beisteuern will, möchte ich natürlich meine Änderungen auf einem Windows-System testen. Hierfür bietet Wine ein &lt;strong&gt;make crosstest&lt;/strong&gt; an. Doch damit dies unter Gentoo funktioniert, muss man folgendes ausführen:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;# emerge crossdev &amp;amp;&amp;amp; crossdev i386-mingw32&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Danach muss man nur noch &lt;strong&gt;./configure &amp;amp;&amp;amp; make crosstest&lt;/strong&gt; im Wine-Verzeichnis ausführen und man bekommt Binaries für Windows.
Happy Hacking&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Nachdem ich im Moment ein paar kleine Patches für Wine beisteuern will, möchte ich natürlich meine Änderungen auf einem Windows-System testen. Hierfür bietet Wine ein <strong>make crosstest</strong> an. Doch damit dies unter Gentoo funktioniert, muss man folgendes ausführen:</p>
<p><strong># emerge crossdev &amp;&amp; crossdev i386-mingw32</strong></p>
<p>Danach muss man nur noch <strong>./configure &amp;&amp; make crosstest</strong> im Wine-Verzeichnis ausführen und man bekommt Binaries für Windows.
Happy Hacking</p>
]]></content:encoded>
    </item>
    <item>
      <title>Chaos Computing...</title>
      <link>https://christian-gmeiner.info/2007-09-18-chaos-computing/</link>
      <pubDate>Tue, 18 Sep 2007 00:00:00 +0000</pubDate>
      <guid>https://christian-gmeiner.info/2007-09-18-chaos-computing/</guid>
      <description>&lt;p&gt;Dies ist mein erneuter Versuchen einen Blog auf Beine zu stellen. Hier werde ich ausschließlich über mein Leben als Informatiker schreiben, über meine Arbeit als Open Source Entwickler und evt ein wenig über mein Studium.&lt;/p&gt;
&lt;p&gt;Happy Reading&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Dies ist mein erneuter Versuchen einen Blog auf Beine zu stellen. Hier werde ich ausschließlich über mein Leben als Informatiker schreiben, über meine Arbeit als Open Source Entwickler und evt ein wenig über mein Studium.</p>
<p>Happy Reading</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
