Skip to content

Latest commit

 

History

222 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

md
==

sun4v Machine Description (MD) / hypervisor-config source, blobs, and
patches for OpenSPARC T1 "niagara" -- the data that tells a sun4v guest
kernel (illumos/OpenSolaris) what CPUs, memory, and virtual devices it
has, and the QEMU-side hv-config that backs it.

This repo is the MD/hv-config content itself. The compiler/linter that
turns .pdesc/.hdesc source into the binary .bin blobs (mdgen,
mdlint) lives separately at github.com/unix0cc/mdbuild -- built there,
installed at $(HOME)/toolchain/mdbuild/bin/, and referenced by path from the
Makefiles here.

This README describes the repo as it currently is. For the history of
notable changes, see CHANGELOG.

Layout
------
src/
    Buildable source only (.pdesc/.hdesc + one Makefile per config).
    Never contains .bin/.txt output or firmware blobs. See src/README.

bin/
    Built blobs only: the pristine, unmodified 2006 Sun original
    release (bin/OpenSPARC_T1_original/, GPLv2, kept exactly as
    shipped -- the one exception to "blobs only"), plus everything
    make produces from src/ for every other config. See bin/README.

patches/
    The fix patch chain (currently patches/t1_boot_fix/) -- both a
    consolidated one-patch-per-source-file view and an incremental
    one-patch-per-feature view (separate-patches/) of the same,
    live-kmdb-proven-minimal MD fix: memory/cpus/cache nodes plus
    mmu-page-size-list/mmu-#va-bits platform properties, required for
    a clean sun4v boot on illumos/OpenSolaris snv_134.

latest
    A symlink in each of the three directories above, pointing at the
    newest config that has been *verified* -- currently pagesize_256m.
    Deliberately not the newest work: the experimental configs under
    _test/ have no row in the boot matrix, and the new-hv-MD-format ones
    additionally need a firmware set this repo does not ship (see
    patches/_test/README). "latest" means the one to reach for, which is
    a claim about evidence, not about dates. It moves when a config earns
    a matrix row, not when a config is written.

fw_blobs/
    The firmware -M niagara loads but mdgen does not produce:

        openboot.bin    OBP 4.20.0
        q.bin           hypervisor
        reset.bin       reset vector
        nvram1          OBP settings

    Byte-identical copies of the same files in the S10image directory of
    the OpenSPARC T1 archive, kept here so that running a config needs
    nothing but a clone of this repository -- the archive is a ~100 MB
    download for four files.

    Deliberately neither copied nor symlinked into each config: a config
    directory holds only its two built blobs, and this directory is given
    to QEMU as a second -L search path. See "Running a config" below.

    Without these, no config here can boot: the MD/hv pair alone is not a
    machine. They are tracked in git, so an accidental removal shows up in
    git status and is undone with "git checkout -- fw_blobs".

    netcons is kept alongside them but -M niagara never loads it -- it is
    a Legion-simulator artefact.

Boot/failure evidence for docs/index.html's test matrix cells lives in
a separate repo, github.com/unix0cc/md-artefacts, published via its
own GitHub Pages site -- so it's visible from the live matrix without
ever being pulled down by a git clone of this repo.

Building a config
------------------
From the repository root, a top-level Makefile drives every config at once:

    make                   # build all configs
    make symlinks          # link fw_blobs into all of them (see below)
    make verify            # run scripts/verify.sh
    make distclean         # remove all built output
    make list              # print the config names
    make tlb_fix/1024      # build one config by name

Or work in a config's own directory, which is what the top-level Makefile
does for each of them:

    cd src/<config>/       # e.g. src/t1_boot_fix/256, src/t1_boot_fix/1024
    make                   # writes the config's .bin/.txt into
                            # the mirrored bin/<config>/ path
    make distclean          # removes that output, leaves src/ untouched
    make symlinks           # opt-in: link fw_blobs in, so one -L suffices

`make symlinks` links nvram1, openboot.bin, q.bin and reset.bin into the
config's bin/ directory, so that a single -L covers all six files QEMU
loads instead of two. The links are relative, so they keep working after a
move or in a fresh clone, and .gitignore keeps them unstageable -- this
repo once carried exactly such links committed and absolute, which left 55
dangling links in every clone made outside /git/md. `make distclean`
removes them along with the rest of the output.

scripts/verify.sh accepts those links but still reports a *copy* of a
firmware blob, since a copy can drift from fw_blobs and shadows any later
-L path at run time.

What make actually does. A config directory holds four sources, and they
compile as two independent chains -- not one pipeline:

    1up.pdesc ----+                        +--> 1up-md.bin   guest MD
                  +-- cpp --> 1up-md.pp ---+
    common.pdesc -+                        +--> 1up-md.txt   readable dump

    1up.hdesc ----+                        +--> 1up-hv.bin   hv-config
                  +-- cpp --> 1up-hv.pp ---+
    common.hdesc -+                        +--> 1up-hv.txt

    *.pdesc  ->  *-md.bin   the guest MD: what the guest OS reads to learn
                            what CPUs, memory and virtual devices it has.
    *.hdesc  ->  *-hv.bin   the hv-config: what the hypervisor uses to back
                            that machine.

common.pdesc/common.hdesc are pulled in by #include and are never
compiled on their own -- which is why four sources yield two blobs, not four.
cpp runs first because the sources use #include and macros; the .pp
intermediates are deleted after the build.

Each chain is run twice, once with mdgen --binary for the .bin and once
with --text for the .txt. Both are committed: the .txt is the readable
twin of an otherwise opaque binary, so a change to a blob is reviewable in a
diff.

Beware the two-layer memory rule: guest RAM size lives in BOTH the MD
(mblock.size) and the hv-config (GUEST() memsize), and both must match
QEMU's -m. Patch one only and OBP reports the new size while the hypervisor
still backs the old one.

The equivalent by hand, if you are building outside this repo, is in the
mdbuild README's Usage section (github.com/unix0cc/mdbuild).

Verifying the committed blobs
------------------------------
    scripts/verify.sh      # rebuilds every config into a temp dir and
                            # compares it against what is committed
    scripts/verify.sh -q   # only report problems

Because this repo commits its built blobs, source and blob can drift
apart: edit a .pdesc, forget to run make, commit, and git will not
complain -- it just shows a changed source next to an unchanged blob.
Every boot result in docs/index.html that cites that config then refers
to something the source no longer produces. verify.sh catches exactly
that, and also flags stray files in a config directory (a firmware blob
copied back in would shadow later -L paths at run time).

It also re-checks the byte-identity proof that OpenSPARC_T1_rebuild/
exists for -- that our mdgen port reproduces Sun's 2006 binaries exactly
-- by comparing both legs of it against
bin/_reference/OpenSPARC_T1_original/niagara/:

    src/OpenSPARC_T1_rebuild/*.pdesc|hdesc  ==  Sun's originals
    bin/OpenSPARC_T1_rebuild/*.bin          ==  Sun's originals

Checking only the blobs would not be enough: edit those "verbatim"
sources, rebuild honestly, and bin/ still matches src/, so the drift
check above stays green while the proof is quietly false. (Comment-only
edits do not even change the output, since cpp strips them -- which the
source comparison catches and a blob comparison never would.)

It writes nothing under bin/, so it is safe to run at any time. Exit 0
means every config matches; 1 means a problem; 2 means it could not
check at all (mdgen missing) -- never 0, so "verify passed" cannot
quietly mean "verify never ran". Worth running before any commit that
touches src/.

The proof covers all three configs Sun shipped -- 1up, 1g2p and 1g32p --
using Sun's own config list from their original niagara/Makefile. That
breadth matters: 1up is a single-strand, single-guest machine, so on its
own it exercises only a fraction of mdgen. 1g2p and 1g32p describe
multiple guests and 32 strands, and 1g32p-md.bin is 9104 bytes against
1up's 2408. All six blobs (md and hv for each) rebuild byte-identical.

Running a config
-----------------
A config directory holds only the two built blobs, so give QEMU both it
and fw_blobs/ -- -L may be repeated, and the paths are searched in the
order given:

    qemu-system-sparc64 -M niagara -nographic -m 2048 \
        -L bin/tlb_fix/2048 \
        -L fw_blobs \
        -drive if=pflash,readonly=on,file=/path/to/disk.s10hw2

This is what repeated -L was added for. QEMU commit 4524051c32 ("Add
search path support for qemu data files", 2013): specifying an
incomplete directory this way means "anything not found there will be
loaded from the default paths, so you don't have to create a symlink
farm for all the rom blobs". The option's own help text was never
updated to describe the repetition, but the behaviour is deliberate and
long-standing.

Two ways to check what actually got used:

    -L help              # prints the search path list, in order
    -trace load_file     # prints the resolved location of each blob loaded

Beware the ordering rule: first match wins. A directory that carries its
own copy of a firmware blob will shadow every -L after it.

If the config was built with `make symlinks`, a single -L path is enough,
because the config directory then holds all six:

    qemu-system-sparc64 -M niagara \
        -L /tmp/md/bin/latest/4096 \
        -nographic -m 4096 \
        -drive if=pflash,readonly=on,file=/zroot/iso/s10u11/V36434-01.iso

The memory size is the last path component, so bin/latest/4096 wants
-m 4096. The four firmware paths are symlinks into fw_blobs, so nothing
was copied and the shadowing rule above has nothing left to bite on. The
full trace of a run in this form is on the project page:
https://unix0cc.github.io/md/

Provenance / licensing
-----------------------
The original OpenSPARC T1 "niagara" .pdesc/.hdesc/.conf sources
and the blobs Sun shipped with them are GPLv2 (see each file's own
header) -- unmodified in bin/OpenSPARC_T1_original/. The mdgen/mdlint
tool source they're compiled with (github.com/unix0cc/mdbuild) is
separately BSD 3-Clause. Patches, Makefiles, and READMEs added in this
repo are new work built on top of the GPLv2 originals.

About

Machine-Description (MD) source code and bindary blobs for qemu-sparc64

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages