Skip to content

mp377-iop13xx support#3

Open
RaulMerelli wants to merge 1 commit into
gweslab:mainfrom
RaulMerelli:main
Open

mp377-iop13xx support#3
RaulMerelli wants to merge 1 commit into
gweslab:mainfrom
RaulMerelli:main

Conversation

@RaulMerelli

Copy link
Copy Markdown
Contributor

Add Siemens MP377 board support

This PR adds support for the Siemens SIMATIC MP377 panel.

It introduces support for the Intel IOP13xx SoC used by this board, adds the Siemens MP377 board definition, and implements the required board devices for a usable boot.

Current status:

  • The board boots successfully.
  • The display works.
  • Touch input works.
  • The SoC is identified as Intel IOP13xx.
  • The board is identified as Siemens SIMATIC MP377.

(a >= 0xC4800028u && a <= 0xC4800034u);
}

class Mp377BoardIoStub : public Peripheral {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silent catch-all MMIO stubs. Mp377BoardIoStub returns 0 / swallows writes with no logging across hundreds of MB of bands, deleting the unmapped-MMIO signal that tells you what to implement next. A bring-up stub must log or fail honestly.

  • The touch/PBI band (0xF2000000) is stubbed silent — touch is mandatory-at-first-hit.
  • MRAM redirected to arbitrary backed DRAM scratch (PA 0x03800000) to dodge an abort — reader-side fault suppression, collision risk.
  • SMI bridge aliased into the 128 MB ATU catch-all and routed to free functions — should be a registered Peripheral at its own base.
  • IDA citations (sub_80446218, 0x81AAF898) unverified by this review.

#include <atomic>
#include <cstdint>

#pragma warning(disable: 4100 4189 4505)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Module-global device state + suppressed warnings.

  • g_mp377_* file-scope statics (atomics + a non-atomic SMI command queue) -> two emulator instances share one touch panel. Must be instance state on a TouchInput/Peripheral.
  • Mixed atomic/non-atomic access to that shared state — threading model not reasoned through.
  • #pragma warning(disable: 4100 4189 4505) hides dead code (4505) and unused vars/params — fix, don't mute.
  • All peripheral logic is free functions over the globals.
  • The pen-up 16-read decaying window is a tuned magic constant to stop the IST spinning — likely masks a real touch-IRQ wiring bug.

Credit: the SMI/ADC burst decode itself is real and source-grounded (sub_29E27C0).


last_down_ = down;
}
void OnWheel(int, int, int) override {}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong base class. A resistive touchscreen derives from PointerInput (the Guest Additions absolute mouse base) instead of TouchInput (stock stylus). This empty OnWheel override is the tell — a touchscreen has no wheel.

Consequence: it inherits the GA-mouse identity (SourceName "Guest Additions mouse", GA icon, SourcePriority 100, Kind::Absolute), so the stock panel impersonates GA and outranks real GA in PointerRouter; loses Kind::Stylus semantics. Fix: re-base to TouchInput (OnPenDown/Move/Up), drop OnWheel — the decode logic transplants unchanged.

ARM ID = 0x69052D06 (0x69 Intel, 0x05 ARMv5TE, core gen 001 =
XScale, product number 010000 = PXA255, revision 0110 = A0). */
uint32_t Midr() const override { return 0x69052D06u; }
uint32_t Midr() const override {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (soc==) inside a strategy impl. One concrete registers for two SoCs (PXA25x || IOP13xx) then branches internally — Midr(), CpuClockHz(), CpuToOscrDivider(), CpuToLowfreqClockDivider(). A strategy concrete is one SoC.

  • Divergence-by-omission: Ctr() and CacheLineSize() are not branched, so IOP13xx (xsc3) silently inherits PXA255's Cache Type Register — a different cache generation. Verify.
  • Stale header ("core as integrated in the PXA255").
  • Fix: shared XscaleProcessorConfigBase + Pxa255/Iop13xx concretes, each ShouldRegister for its own SoC, zero ternaries.

DecodedInsn* d,
BlockContext* ctx) override {
auto* bd = emu_.TryGet<BoardDetector>();
if (d->cp_num == 6 && bd && bd->GetSoc() == SocFamily::IOP13xx) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (soc==IOP13xx) inside the JIT emit body (EmitRegisterTransfer) routing cp6 to Iop13xxCp6. Forbidden in the JIT body. Same two-SoC concrete as xscale_processor_config.cpp.

Fix: a capability flag (e.g. HasCp6InterruptController()) routed in the shared path, or an Iop13xx emitter concrete.

Credit: the emit body (CPAR, the c14 debug-reg whitelist that FATALs, allocate-cache-line, aux control, MAR/MRA on CP0 acc0) is careful, cited, and correct.

break;
}
default:
/* Unknown command — leave state alone; CSR completion code

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best-structured peripheral chassis in the PR (instance state, no globals, real command FSM, bounds-checked, cited) — but:

  • Fake-success flash stub (data loss): RunCommand's default ignores an unknown command yet reports completion 0x80008000 + ctrl_status_=0 (success). On the device backing the filesystem, an unmodeled program/erase is dropped while the driver is told it succeeded -> silent corruption. Must FATAL.
  • Unknown register read/write defaults (RegRead16->0, RegWrite16->drop) must FATAL-or-implement, not silently 0/drop. (Erased data-buffer reads of 0xFFFF are legit — real flash.)
  • Geometry self-contradiction: header says 32 MB / 2 KB page / 64 B spare; constants say 256 MB / 4 KB / 128 B; kBlocks=2048 ("256 MB") is unused and = 512 MB at 4 KB pages. Pin the real geometry and reconcile.
  • kBlocks is dead.
  • Hibernation: no SaveState/RestoreState despite holding the whole flash array -> save/restore loses the filesystem.


constexpr uint32_t MB(uint32_t mb) { return mb * 0x100000u; }

enum class OatKind { Dram, Mmio };

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean chassis; OAT internally consistent and agrees with the peripheral bands; VaToPa FATALs loudly. One finding:

  • OatKind enum + .kind field is dead — set on every entry, never read. CachedDramRegions/BackedMemoryRegions hardcode the DRAM region as literals instead of deriving from the table — and the kind taxonomy can't express the uncached DRAM alias, which is why. Either wire it (add an UncachedAlias kind, derive the lists) or delete the enum/field.
  • Soft: InitStackTopPa()=top-of-DRAM uncited; OAT triplets owe a check vs nk.exe @ 0x80409F00 (IDA).

uint32_t RegStride() const override { return 4u; }
const char* Name() const override { return "UART0"; }

void SetInterruptLine(bool pending) override {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Model file — the right way to add a SoC peripheral: derives the shared Uart16550, proper service, grounded RegStride()=4, TX works, and SetInterruptLine(pending=true) -> HaltUnsupportedAccess is the correct loud, documented bring-up stub. Two nits: dead #include "iop13xx_cp6.h" (unused), and the size comment says 0x2C while MmioSize() returns 0x30 (the 0x30 is correct — fix the comment).

bit2 = RGN[0], bit3 = P, bit4 = RGN[1]. Default (v4/v5 non-XScale,
v6, v7) writes SBZ in [13:0] and the JIT-side store must reject
non-zero low bits. */
virtual bool HasXscaleTtbrAttrs() const { return false; }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HasXscaleTtbrAttrs() is a default-false capability flag — the correct pattern, and the one emit_cp15_cache_op.cpp should have used to gate its change.


uint32_t Mp377SmiBridgeRead(uint32_t pa);
void Mp377SmiBridgeWrite(uint32_t pa, uint32_t value);
void Mp377SmiBindEmulator(CerfEmulator* emu);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declaration surface for violations logged on sm501.cpp: Mp377SmiBindEmulator(CerfEmulator*) (the API whose purpose is to stash the emulator in a static), the Sm501*(CerfEmulator&) accessors (free-fns taking a service), and the kFb* constants duplicated into sm501.cpp. These change when those .cpp violations are fixed.

@dz333n

dz333n commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

☝️ Automated code review — PR #3 (mp377-iop13xx)

Claude-assisted review. Per-file findings are inline comments below.

Severity: each item is a CLAUDE.md / agent_docs rule violation or a concrete correctness defect; treat as must-fix before merge. The reverse-engineering is frequently strong; most findings are structural (how correct logic is integrated). Inline "Credit" notes mark what's done well.

Recurring violations (sites in the inline comments): module-global state breaking multi-instance; a cached CerfEmulator* in a static; #pragma warning(disable ...); peripheral logic as free functions / free-fns taking CerfEmulator&; silent and fake-success stubs; bloated comments throughout; the 500-line cap (sm501.cpp ~990); DRY (triplicated SMI decode, duplicated constants); if (soc==) inside a strategy.

Launcher registration (missing): launcher/supported_devices.py is not in the PR. Add a SiemensMP377 entry so the board appears in the launcher and its features

Tooling: the ~990-line file reaching the PR means neither project guard fired for this contribution — .githooks/pre-commit (500-line cap; needs git config core.hooksPath .githooks) and the project Claude hook .claude/hooks/check_cerf_file.py (PostToolUse, py -3). Worth finding out why both were inert (hooks path unset, Claude not launched from repo root, or py -3 not resolving).

Disclaimer: generated automatically by Claude (Anthropic); may contain misunderstandings or errors — treat as input to human review, not ground truth. Items needing IDA/datasheet checks (IOP13xx register map, XScale Table 7-12, OAT vs nk.exe, the SM501 magic constants, the XScale Ctr value) are flagged inline as unverified.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants