qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Brian Cain <brian.cain@oss.qualcomm.com>
To: qemu-devel@nongnu.org
Cc: brian.cain@oss.qualcomm.com, richard.henderson@linaro.org,
	philmd@linaro.org, matheus.bernardino@oss.qualcomm.com,
	ale@rev.ng, anjo@rev.ng, marco.liebel@oss.qualcomm.com,
	ltaylorsimpson@gmail.com, alex.bennee@linaro.org,
	quic_mburton@quicinc.com, sid.manning@oss.qualcomm.com,
	Brian Cain <bcain@quicinc.com>
Subject: [PATCH v2 18/40] target/hexagon: Add new macro definitions for sysemu
Date: Mon,  1 Sep 2025 20:46:53 -0700	[thread overview]
Message-ID: <20250902034715.1947718-19-brian.cain@oss.qualcomm.com> (raw)
In-Reply-To: <20250902034715.1947718-1-brian.cain@oss.qualcomm.com>

From: Brian Cain <bcain@quicinc.com>

Also: add nop TCG overrides for break,unpause,fetchbo,dczeroa

break: this hardware breakpoint instruction is used with the in-silicon
debugger feature, this is not modeled.

unpause: this instruction is used to resume hardware threads that are
stalled by pause instructions.  pause is modeled as a nop, or in RR
mode as an EXCP_YIELD.  This instruction is safe to ignore.

Since cache/prefetch functions are not modeled, dczero and fetchbo are
safe to ignore.

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 target/hexagon/gen_tcg.h    |   9 ++
 target/hexagon/macros.h     |  30 ++++-
 target/hexagon/sys_macros.h | 238 ++++++++++++++++++++++++++++++++++++
 target/hexagon/op_helper.c  |   1 +
 4 files changed, 274 insertions(+), 4 deletions(-)
 create mode 100644 target/hexagon/sys_macros.h

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 8a3b801287..71f8a0e2d0 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -488,6 +488,7 @@
 
 /* dczeroa clears the 32 byte cache line at the address given */
 #define fGEN_TCG_Y2_dczeroa(SHORTCODE) SHORTCODE
+#define fGEN_TCG_Y2_dczeroa_nt(SHORTCODE) SHORTCODE
 
 /* In linux-user mode, these are not modelled, suppress compiler warning */
 #define fGEN_TCG_Y2_dcinva(SHORTCODE) \
@@ -1133,6 +1134,9 @@
                            RdV, tcg_constant_tl(0)); \
     } while (0)
 
+#define fGEN_TCG_Y2_break(SHORTCODE)
+#define fGEN_TCG_J2_unpause(SHORTCODE)
+
 #define fGEN_TCG_J2_pause(SHORTCODE) \
     do { \
         uiV = uiV; \
@@ -1342,6 +1346,11 @@
         RsV = RsV; \
         uiV = uiV; \
     } while (0)
+#define fGEN_TCG_Y2_dcfetchbo_nt(SHORTCODE) \
+    do { \
+        RsV = RsV; \
+        uiV = uiV; \
+    } while (0)
 
 #define fGEN_TCG_L2_loadw_aq(SHORTCODE)                 SHORTCODE
 #define fGEN_TCG_L4_loadd_aq(SHORTCODE)                 SHORTCODE
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 9ba9be408d..4823c97fde 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -538,9 +538,6 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
 
 #ifdef CONFIG_USER_ONLY
 #define fFRAMECHECK(ADDR, EA) do { } while (0) /* Not modelled in linux-user */
-#else
-/* System mode not implemented yet */
-#define fFRAMECHECK(ADDR, EA)  g_assert_not_reached();
 #endif
 
 #ifdef QEMU_GENERATE
@@ -631,8 +628,18 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
 #define fCONSTLL(A) A##LL
 #define fECHO(A) (A)
 
-#define fTRAP(TRAPTYPE, IMM) helper_raise_exception(env, HEX_EXCP_TRAP0)
+#ifdef CONFIG_USER_ONLY
+#define fTRAP(TRAPTYPE, IMM) \
+    do { \
+        hexagon_raise_exception_err(env, HEX_EVENT_TRAP0, PC); \
+    } while (0)
+#endif
+
+#define fDO_TRACE(SREG)
+#define fBREAK()
+#define fUNPAUSE()
 #define fPAUSE(IMM)
+#define fDCFETCH(REG)
 
 #define fALIGN_REG_FIELD_VALUE(FIELD, VAL) \
     ((VAL) << reg_field_info[FIELD].offset)
@@ -649,10 +656,25 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
         ctx->dczero_addr = tcg_temp_new(); \
         tcg_gen_mov_tl(ctx->dczero_addr, (REG)); \
     } while (0)
+#else
+#define fDCZEROA(REG) ((void) REG)
 #endif
 
 #define fBRANCH_SPECULATE_STALL(DOTNEWVAL, JUMP_COND, SPEC_DIR, HINTBITNUM, \
                                 STRBITNUM) /* Nothing */
 
+#ifdef CONFIG_USER_ONLY
+/*
+ * This macro can only be true in guest mode.
+ * In user mode, the 4 VIRTINSN's can't be reached
+ */
+#define fTRAP1_VIRTINSN(IMM)       (false)
+#define fVIRTINSN_SPSWAP(IMM, REG) g_assert_not_reached()
+#define fVIRTINSN_GETIE(IMM, REG)  g_assert_not_reached()
+#define fVIRTINSN_SETIE(IMM, REG)  g_assert_not_reached()
+#define fVIRTINSN_RTE(IMM, REG)    g_assert_not_reached()
+#endif
 
 #endif
+
+#define fPREDUSE_TIMING()
diff --git a/target/hexagon/sys_macros.h b/target/hexagon/sys_macros.h
new file mode 100644
index 0000000000..3c4c3c7aa5
--- /dev/null
+++ b/target/hexagon/sys_macros.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright(c) 2019-2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HEXAGON_SYS_MACROS_H
+#define HEXAGON_SYS_MACROS_H
+
+/*
+ * Macro definitions for Hexagon system mode
+ */
+
+#ifndef CONFIG_USER_ONLY
+
+#define READ_SREG(NUM) arch_get_system_reg(env, NUM)
+#define READ_SGP0()    arch_get_system_reg(env, HEX_SREG_SGP0)
+#define READ_SGP1()    arch_get_system_reg(env, HEX_SREG_SGP1)
+#define READ_SGP10()   ((uint64_t)arch_get_system_reg(env, HEX_SREG_SGP0) | \
+    ((uint64_t)arch_get_system_reg(env, HEX_SREG_SGP1) << 32))
+
+#define WRITE_SREG(NUM, VAL)      log_sreg_write(env, NUM, VAL, slot)
+#define WRITE_SGP0(VAL)           log_sreg_write(env, HEX_SREG_SGP0, VAL, slot)
+#define WRITE_SGP1(VAL)           log_sreg_write(env, HEX_SREG_SGP1, VAL, slot)
+#define WRITE_SGP10(VAL) \
+    do { \
+        log_sreg_write(env, HEX_SREG_SGP0, (VAL) & 0xFFFFFFFF, slot); \
+        log_sreg_write(env, HEX_SREG_SGP1, (VAL) >> 32, slot); \
+    } while (0)
+
+#ifdef QEMU_GENERATE
+#define GET_SSR_FIELD(RES, FIELD) \
+    GET_FIELD(RES, FIELD, hex_t_sreg[HEX_SREG_SSR])
+#else
+
+#define GET_SSR_FIELD(FIELD, REGIN) \
+    (uint32_t)GET_FIELD(FIELD, REGIN)
+#define GET_SYSCFG_FIELD(FIELD, REGIN) \
+    (uint32_t)GET_FIELD(FIELD, REGIN)
+#define SET_SYSTEM_FIELD(ENV, REG, FIELD, VAL) \
+    do { \
+        uint32_t regval = arch_get_system_reg(ENV, REG); \
+        fINSERT_BITS(regval, reg_field_info[FIELD].width, \
+                     reg_field_info[FIELD].offset, (VAL)); \
+        arch_set_system_reg(ENV, REG, regval); \
+    } while (0)
+#define SET_SSR_FIELD(ENV, FIELD, VAL) \
+    SET_SYSTEM_FIELD(ENV, HEX_SREG_SSR, FIELD, VAL)
+#define SET_SYSCFG_FIELD(ENV, FIELD, VAL) \
+    SET_SYSTEM_FIELD(ENV, HEX_SREG_SYSCFG, FIELD, VAL)
+
+#define CCR_FIELD_SET(ENV, FIELD) \
+    (!!GET_FIELD(FIELD, arch_get_system_reg(ENV, HEX_SREG_CCR)))
+
+/*
+ * Direct-to-guest is not implemented yet, continuing would cause unexpected
+ * behavior, so we abort.
+ */
+#define ASSERT_DIRECT_TO_GUEST_UNSET(ENV, EXCP) \
+    do { \
+        switch (EXCP) { \
+        case HEX_EVENT_TRAP0: \
+            g_assert(!CCR_FIELD_SET(ENV, CCR_GTE)); \
+            break; \
+        case HEX_EVENT_IMPRECISE: \
+        case HEX_EVENT_PRECISE: \
+        case HEX_EVENT_FPTRAP: \
+            g_assert(!CCR_FIELD_SET(ENV, CCR_GEE)); \
+            break; \
+        default: \
+            if ((EXCP) >= HEX_EVENT_INT0) { \
+                g_assert(!CCR_FIELD_SET(ENV, CCR_GIE)); \
+            } \
+            break; \
+        } \
+    } while (0)
+#endif
+
+#define fREAD_ELR() (READ_SREG(HEX_SREG_ELR))
+
+#define fLOAD_PHYS(NUM, SIZE, SIGN, SRC1, SRC2, DST) { \
+  const uintptr_t rs = ((unsigned long)(unsigned)(SRC1)) & 0x7ff; \
+  const uintptr_t rt = ((unsigned long)(unsigned)(SRC2)) << 11; \
+  const uintptr_t addr = rs + rt;         \
+  cpu_physical_memory_read(addr, &DST, sizeof(uint32_t)); \
+}
+
+#define fPOW2_HELP_ROUNDUP(VAL) \
+    ((VAL) | \
+     ((VAL) >> 1) | \
+     ((VAL) >> 2) | \
+     ((VAL) >> 4) | \
+     ((VAL) >> 8) | \
+     ((VAL) >> 16))
+#define fPOW2_ROUNDUP(VAL) (fPOW2_HELP_ROUNDUP((VAL) - 1) + 1)
+
+#define fFRAMECHECK(ADDR, EA)  g_assert_not_reached();
+
+#define fTRAP(TRAPTYPE, IMM) \
+    register_trap_exception(env, TRAPTYPE, IMM, PC)
+
+#define fVIRTINSN_SPSWAP(IMM, REG)
+#define fVIRTINSN_GETIE(IMM, REG) { REG = 0xdeafbeef; }
+#define fVIRTINSN_SETIE(IMM, REG)
+#define fVIRTINSN_RTE(IMM, REG)
+#define fGRE_ENABLED() GET_FIELD(CCR_GRE, READ_SREG(HEX_SREG_CCR))
+#define fTRAP1_VIRTINSN(IMM) \
+    (fGRE_ENABLED() && \
+        (((IMM) == 1) || ((IMM) == 3) || ((IMM) == 4) || ((IMM) == 6)))
+
+/* Not modeled in qemu */
+
+#define MARK_LATE_PRED_WRITE(RNUM)
+#define fICINVIDX(REG)
+#define fICKILL()
+#define fDCKILL()
+#define fL2KILL()
+#define fL2UNLOCK()
+#define fL2CLEAN()
+#define fL2CLEANINV()
+#define fL2CLEANPA(REG)
+#define fL2CLEANINVPA(REG)
+#define fL2CLEANINVIDX(REG)
+#define fL2CLEANIDX(REG)
+#define fL2INVIDX(REG)
+#define fL2TAGR(INDEX, DST, DSTREG)
+#define fL2UNLOCKA(VA) ((void) VA)
+#define fL2TAGW(INDEX, PART2)
+#define fDCCLEANIDX(REG)
+#define fDCCLEANINVIDX(REG)
+
+/* Always succeed: */
+#define fL2LOCKA(EA, PDV, PDN) ((void) EA, PDV = 0xFF)
+#define fCLEAR_RTE_EX() \
+    do { \
+        uint32_t tmp = 0; \
+        tmp = arch_get_system_reg(env, HEX_SREG_SSR); \
+        fINSERT_BITS(tmp, reg_field_info[SSR_EX].width, \
+                     reg_field_info[SSR_EX].offset, 0); \
+        log_sreg_write(env, HEX_SREG_SSR, tmp, slot); \
+    } while (0)
+
+#define fDCINVIDX(REG)
+#define fDCINVA(REG) do { REG = REG; } while (0) /* Nothing to do in qemu */
+
+#define fSET_TLB_LOCK()       g_assert_not_reached()
+#define fCLEAR_TLB_LOCK()     g_assert_not_reached()
+
+#define fSET_K0_LOCK()        g_assert_not_reached()
+#define fCLEAR_K0_LOCK()      g_assert_not_reached()
+
+#define fTLB_IDXMASK(INDEX) \
+    ((INDEX) & (fPOW2_ROUNDUP(fCAST4u(env_archcpu(env)->num_tlbs)) - 1))
+
+#define fTLB_NONPOW2WRAP(INDEX)                 \
+    (((INDEX) >= env_archcpu(env)->num_tlbs) ?  \
+         ((INDEX) - env_archcpu(env)->num_tlbs) : \
+         (INDEX))
+
+
+#define fTLBW(INDEX, VALUE) \
+    hex_tlbw(env, (INDEX), (VALUE))
+#define fTLBW_EXTENDED(INDEX, VALUE) \
+    hex_tlbw(env, (INDEX), (VALUE))
+#define fTLB_ENTRY_OVERLAP(VALUE) \
+    (hex_tlb_check_overlap(env, VALUE, -1) != -2)
+#define fTLB_ENTRY_OVERLAP_IDX(VALUE) \
+    hex_tlb_check_overlap(env, VALUE, -1)
+#define fTLBR(INDEX) \
+    (env->hex_tlb->entries[fTLB_NONPOW2WRAP(fTLB_IDXMASK(INDEX))])
+#define fTLBR_EXTENDED(INDEX) \
+    (env->hex_tlb->entries[fTLB_NONPOW2WRAP(fTLB_IDXMASK(INDEX))])
+#define fTLBP(TLBHI) \
+    hex_tlb_lookup(env, ((TLBHI) >> 12), ((TLBHI) << 12))
+#define iic_flush_cache(p)
+
+#define fIN_DEBUG_MODE(TNUM) \
+    ((GET_FIELD(ISDBST_DEBUGMODE, arch_get_system_reg(env, HEX_SREG_ISDBST)) \
+        & (0x1 << (TNUM))) != 0)
+
+#define fIN_DEBUG_MODE_NO_ISDB(TNUM) false
+#define fIN_DEBUG_MODE_WARN(TNUM) false
+
+#ifdef QEMU_GENERATE
+
+/*
+ * Read tags back as zero for now:
+ *
+ * tag value in RD[31:10] for 32k, RD[31:9] for 16k
+ */
+#define fICTAGR(RS, RD, RD2) \
+    do { \
+        RD = ctx->zero; \
+    } while (0)
+#define fICTAGW(RS, RD)
+#define fICDATAR(RS, RD) \
+    do { \
+        RD = ctx->zero; \
+    } while (0)
+#define fICDATAW(RS, RD)
+
+#define fDCTAGW(RS, RT)
+/* tag: RD[23:0], state: RD[30:29] */
+#define fDCTAGR(INDEX, DST, DST_REG_NUM) \
+    do { \
+        DST = ctx->zero; \
+    } while (0)
+#else
+
+/*
+ * Read tags back as zero for now:
+ *
+ * tag value in RD[31:10] for 32k, RD[31:9] for 16k
+ */
+#define fICTAGR(RS, RD, RD2) \
+    do { \
+        RD = 0x00; \
+    } while (0)
+#define fICTAGW(RS, RD)
+#define fICDATAR(RS, RD) \
+    do { \
+        RD = 0x00; \
+    } while (0)
+#define fICDATAW(RS, RD)
+
+#define fDCTAGW(RS, RT)
+/* tag: RD[23:0], state: RD[30:29] */
+#define fDCTAGR(INDEX, DST, DST_REG_NUM) \
+    do { \
+        DST = HEX_DC_STATE_INVALID | 0x00; \
+    } while (0)
+#endif
+
+#endif
+
+#define NUM_TLB_REGS(x) (env_archcpu(env)->num_tlbs)
+
+#endif
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 444799d3ad..c3140b97bd 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -24,6 +24,7 @@
 #include "cpu.h"
 #include "internal.h"
 #include "macros.h"
+#include "sys_macros.h"
 #include "arch.h"
 #include "hex_arch_types.h"
 #include "fma_emu.h"
-- 
2.34.1



  parent reply	other threads:[~2025-09-02  4:10 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-02  3:46 [PATCH v2 00/40] hexagon system emulation v2, part 1/3 Brian Cain
2025-09-02  3:46 ` [PATCH v2 01/40] docs: Add hexagon sysemu docs Brian Cain
2025-09-02  3:46 ` [PATCH v2 02/40] docs/system: Add hexagon CPU emulation Brian Cain
2025-09-02  3:46 ` [PATCH v2 03/40] target/hexagon: Fix badva reference, delete CAUSE Brian Cain
2025-09-02  3:46 ` [PATCH v2 04/40] target/hexagon: Add missing A_CALL attr, hintjumpr to multi_cof Brian Cain
2025-09-02  3:46 ` [PATCH v2 05/40] target/hexagon: Handle system/guest registers in gen_analyze_funcs.py and hex_common.py Brian Cain
2025-09-02  3:46 ` [PATCH v2 06/40] target/hexagon: Make gen_exception_end_tb non-static Brian Cain
2025-09-02  3:46 ` [PATCH v2 07/40] target/hexagon: Switch to tag_ignore(), generate via get_{user, sys}_tags() Brian Cain via
2025-09-02  3:46 ` [PATCH v2 08/40] target/hexagon: Add system event, cause codes Brian Cain
2025-09-02  3:46 ` [PATCH v2 09/40] target/hexagon: Add privilege check, use tag_ignore() Brian Cain
2025-09-02  3:46 ` [PATCH v2 10/40] target/hexagon: Add memory order definition Brian Cain
2025-09-02  3:46 ` [PATCH v2 11/40] target/hexagon: Add a placeholder fp exception Brian Cain
2025-09-02  3:46 ` [PATCH v2 12/40] target/hexagon: Add guest, system reg number defs Brian Cain
2025-09-02  3:46 ` [PATCH v2 13/40] target/hexagon: Add guest, system reg number state Brian Cain
2025-09-02  3:46 ` [PATCH v2 14/40] target/hexagon: Add TCG values for sreg, greg Brian Cain
2025-09-02  3:46 ` [PATCH v2 15/40] target/hexagon: Add guest/sys reg writes to DisasContext Brian Cain
2025-09-02  3:46 ` [PATCH v2 16/40] target/hexagon: Add imported macro, attr defs for sysemu Brian Cain
2025-09-02  3:46 ` [PATCH v2 17/40] target/hexagon: Define DCache states Brian Cain
2025-09-02  3:46 ` Brian Cain [this message]
2025-09-02  3:46 ` [PATCH v2 19/40] target/hexagon: Add handlers for guest/sysreg r/w Brian Cain
2025-09-02  3:46 ` [PATCH v2 20/40] target/hexagon: Add placeholder greg/sreg r/w helpers Brian Cain
2025-09-02  3:46 ` [PATCH v2 21/40] target/hexagon: Add vmstate representation Brian Cain
2025-09-02  3:46 ` [PATCH v2 22/40] target/hexagon: Make A_PRIV, "J2_trap*" insts need_env() Brian Cain
2025-09-02  3:46 ` [PATCH v2 23/40] target/hexagon: Define register fields for system regs Brian Cain
2025-09-02  3:46 ` [PATCH v2 24/40] target/hexagon: Implement do_raise_exception() Brian Cain
2025-09-02  3:47 ` [PATCH v2 25/40] target/hexagon: Add system reg insns Brian Cain
2025-09-02  3:47 ` [PATCH v2 26/40] target/hexagon: Add sysemu TCG overrides Brian Cain
2025-09-02  3:47 ` [PATCH v2 27/40] target/hexagon: Add implicit attributes to sysemu macros Brian Cain
2025-09-02  3:47 ` [PATCH v2 28/40] target/hexagon: Add TCG overrides for int handler insts Brian Cain
2025-09-02  3:47 ` [PATCH v2 29/40] target/hexagon: Add TCG overrides for thread ctl Brian Cain
2025-09-02  3:47 ` [PATCH v2 30/40] target/hexagon: Add TCG overrides for rte, nmi Brian Cain
2025-09-02  3:47 ` [PATCH v2 31/40] target/hexagon: Add sreg_{read,write} helpers Brian Cain
2025-09-02  3:47 ` [PATCH v2 32/40] target/hexagon: Add locks, id, next_PC to state Brian Cain
2025-09-02  3:47 ` [PATCH v2 33/40] target/hexagon: Add a TLB count property Brian Cain
2025-09-02  3:47 ` [PATCH v2 34/40] target/hexagon: Add {TLB, k0}lock, cause code, wait_next_pc Brian Cain via
2025-09-02  3:47 ` [PATCH v2 35/40] target/hexagon: Add stubs for modify_ssr/get_exe_mode Brian Cain
2025-09-02  3:47 ` [PATCH v2 36/40] target/hexagon: Add gdb support for sys regs Brian Cain
2025-09-02  3:47 ` [PATCH v2 37/40] target/hexagon: Add initial MMU model Brian Cain
2025-09-02  3:47 ` [PATCH v2 38/40] target/hexagon: Add clear_wait_mode() definition Brian Cain
2025-09-02  3:47 ` [PATCH v2 39/40] target/hexagon: Define f{S,G}ET_FIELD macros Brian Cain
2025-09-02  3:47 ` [PATCH v2 40/40] target/hexagon: Add hex_interrupts support Brian Cain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250902034715.1947718-19-brian.cain@oss.qualcomm.com \
    --to=brian.cain@oss.qualcomm.com \
    --cc=ale@rev.ng \
    --cc=alex.bennee@linaro.org \
    --cc=anjo@rev.ng \
    --cc=bcain@quicinc.com \
    --cc=ltaylorsimpson@gmail.com \
    --cc=marco.liebel@oss.qualcomm.com \
    --cc=matheus.bernardino@oss.qualcomm.com \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=quic_mburton@quicinc.com \
    --cc=richard.henderson@linaro.org \
    --cc=sid.manning@oss.qualcomm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).