From c0f93ec1914e00354a312e4e6176c6f871f7296a Mon Sep 17 00:00:00 2001 From: jmcneill Date: Thu, 25 Jan 2024 11:47:53 +0000 Subject: [PATCH] wii: Add External interface bus and RTC support --- sys/arch/evbppc/conf/WII | 4 +- sys/arch/evbppc/conf/files.wii | 11 +- sys/arch/evbppc/include/wii.h | 6 +- sys/arch/evbppc/wii/dev/exi.c | 348 ++++++++++++++++++++++++++++++ sys/arch/evbppc/wii/dev/exi.h | 44 ++++ sys/arch/evbppc/wii/dev/rtcsram.c | 177 +++++++++++++++ sys/arch/evbppc/wii/mainbus.c | 9 +- 7 files changed, 594 insertions(+), 5 deletions(-) create mode 100644 sys/arch/evbppc/wii/dev/exi.c create mode 100644 sys/arch/evbppc/wii/dev/exi.h create mode 100644 sys/arch/evbppc/wii/dev/rtcsram.c diff --git a/sys/arch/evbppc/conf/WII b/sys/arch/evbppc/conf/WII index 7ef6b521597f..f5bebb334d25 100644 --- a/sys/arch/evbppc/conf/WII +++ b/sys/arch/evbppc/conf/WII @@ -1,4 +1,4 @@ -# $NetBSD: WII,v 1.3 2024/01/23 21:48:12 jmcneill Exp $ +# $NetBSD: WII,v 1.4 2024/01/25 11:47:53 jmcneill Exp $ # # Nintendo Wii # @@ -128,6 +128,8 @@ options WSDISPLAY_DEFAULTSCREENS=4 options WSDISPLAY_SCROLLSUPPORT hollywood0 at mainbus0 irq 14 +exi0 at mainbus0 addr 0x0d006800 irq 4 # External interface +rtcsram0 at exi0 # RTC/SRAM chip bwai0 at mainbus0 addr 0x0d006c00 irq 5 # Audio interface bwdsp0 at mainbus0 addr 0x0c005000 irq 6 # DSP diff --git a/sys/arch/evbppc/conf/files.wii b/sys/arch/evbppc/conf/files.wii index bc4c3f4fdf07..b05f53981c81 100644 --- a/sys/arch/evbppc/conf/files.wii +++ b/sys/arch/evbppc/conf/files.wii @@ -1,4 +1,4 @@ -# $NetBSD: files.wii,v 1.3 2024/01/23 21:48:12 jmcneill Exp $ +# $NetBSD: files.wii,v 1.4 2024/01/25 11:47:53 jmcneill Exp $ # # maxpartitions 16 @@ -47,6 +47,15 @@ device bwdsp: audiobus attach bwdsp at mainbus file arch/evbppc/wii/dev/bwdsp.c bwdsp +define exi { } +device exi: exi +attach exi at mainbus +file arch/evbppc/wii/dev/exi.c exi + +device rtcsram +attach rtcsram at exi +file arch/evbppc/wii/dev/rtcsram.c rtcsram + define hollywood { [addr=-1], [irq=-1] } device hollywood: hollywood attach hollywood at mainbus diff --git a/sys/arch/evbppc/include/wii.h b/sys/arch/evbppc/include/wii.h index b5a3f2b50031..8651b599f7c7 100644 --- a/sys/arch/evbppc/include/wii.h +++ b/sys/arch/evbppc/include/wii.h @@ -1,4 +1,4 @@ -/* $NetBSD: wii.h,v 1.6 2024/01/24 21:53:34 jmcneill Exp $ */ +/* $NetBSD: wii.h,v 1.7 2024/01/25 11:47:53 jmcneill Exp $ */ /*- * Copyright (c) 2024 Jared McNeill @@ -57,6 +57,9 @@ #define DSP_BASE 0x0c005000 #define DSP_SIZE 0x00000200 +#define EXI_BASE 0x0d006800 +#define EXI_SIZE 0x00000080 + #define AI_BASE 0x0d006c00 #define AI_SIZE 0x00000020 @@ -96,6 +99,7 @@ #define PI_INTMR (PI_BASE + 0x04) /* Processor IRQs */ +#define PI_IRQ_EXI 4 #define PI_IRQ_AI 5 #define PI_IRQ_DSP 6 #define PI_IRQ_HOLLYWOOD 14 diff --git a/sys/arch/evbppc/wii/dev/exi.c b/sys/arch/evbppc/wii/dev/exi.c new file mode 100644 index 000000000000..c793485eadf1 --- /dev/null +++ b/sys/arch/evbppc/wii/dev/exi.c @@ -0,0 +1,348 @@ +/* $NetBSD: exi.c,v 1.1 2024/01/25 11:47:53 jmcneill Exp $ */ + +/*- + * Copyright (c) 2024 Jared McNeill + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: exi.c,v 1.1 2024/01/25 11:47:53 jmcneill Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "locators.h" +#include "mainbus.h" +#include "exi.h" + +#define EXI_NUM_CHAN 3 +#define EXI_NUM_DEV 3 + +/* This is an arbitrary limit. The real limit is probably much higher. */ +#define EXI_MAX_DMA 4096 + +#define EXI_CSR(n) (0x00 + (n) * 0x14) +#define EXI_CSR_CS __BITS(9,7) +#define EXI_MAR(n) (0x04 + (n) * 0x14) +#define EXI_LENGTH(n) (0x08 + (n) * 0x14) +#define EXI_CR(n) (0x0c + (n) * 0x14) +#define EXI_CR_TLEN __BITS(5,4) +#define EXI_CR_RW __BITS(3,2) +#define EXI_CR_RW_READ __SHIFTIN(0, EXI_CR_RW) +#define EXI_CR_RW_WRITE __SHIFTIN(1, EXI_CR_RW) +#define EXI_CR_DMA __BIT(1) +#define EXI_CR_TSTART __BIT(0) +#define EXI_DATA(n) (0x10 + (n) * 0x14) + +#define ASSERT_CHAN_VALID(chan) KASSERT((chan) >= 0 && (chan) < EXI_NUM_CHAN) +#define ASSERT_DEV_VALID(dev) KASSERT((dev) >= 0 && (dev) < EXI_NUM_DEV) +#define ASSERT_LEN_VALID(len) KASSERT((len) == 1 || (len) == 2 || (len) == 4) + +struct exi_channel { + kmutex_t ch_lock; + + bus_dmamap_t ch_dmamap; + + device_t ch_child[EXI_NUM_DEV]; +}; + +struct exi_softc { + device_t sc_dev; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + bus_dma_tag_t sc_dmat; + + struct exi_channel sc_chan[EXI_NUM_CHAN]; +}; + +static struct exi_softc *exi_softc; + +#define RD4(sc, reg) \ + bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) +#define WR4(sc, reg, val) \ + bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) + +static int exi_match(device_t, cfdata_t, void *); +static void exi_attach(device_t, device_t, void *); + +static int exi_rescan(device_t, const char *, const int *); +static int exi_print(void *, const char *); + +CFATTACH_DECL_NEW(exi, sizeof(struct exi_softc), + exi_match, exi_attach, NULL, NULL); + +static int +exi_match(device_t parent, cfdata_t cf, void *aux) +{ + struct mainbus_attach_args *maa = aux; + + return strcmp(maa->maa_name, "exi") == 0; +} + +static void +exi_attach(device_t parent, device_t self, void *aux) +{ + struct mainbus_attach_args * const maa = aux; + struct exi_softc * const sc = device_private(self); + uint8_t chan; + int error; + + KASSERT(device_unit(self) == 0); + + aprint_naive("\n"); + aprint_normal(": External Interface\n"); + + exi_softc = sc; + sc->sc_dev = self; + sc->sc_bst = maa->maa_bst; + if (bus_space_map(sc->sc_bst, maa->maa_addr, EXI_SIZE, 0, + &sc->sc_bsh) != 0) { + aprint_error_dev(self, "couldn't map registers\n"); + return; + } + sc->sc_dmat = maa->maa_dmat; + for (chan = 0; chan < EXI_NUM_CHAN; chan++) { + mutex_init(&sc->sc_chan[chan].ch_lock, MUTEX_DEFAULT, IPL_VM); + error = bus_dmamap_create(exi_softc->sc_dmat, EXI_MAX_DMA, 1, + EXI_MAX_DMA, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, + &sc->sc_chan[chan].ch_dmamap); + if (error != 0) { + aprint_error_dev(self, "couldn't create dmamap: %d\n", + error); + return; + } + } + + exi_rescan(self, NULL, NULL); +} + +static int +exi_rescan(device_t self, const char *ifattr, const int *locs) +{ + struct exi_softc * const sc = device_private(self); + uint8_t chan, dev; + + for (chan = 0; chan < EXI_NUM_CHAN; chan++) { + struct exi_channel *ch = &sc->sc_chan[chan]; + for (dev = 0; dev < EXI_NUM_DEV; dev++) { + struct exi_attach_args eaa = {}; + uint16_t command = 0x0000; /* ID command */ + uint32_t id = 0; + + if (ch->ch_child[dev] != NULL) { + continue; + } + + exi_select(chan, dev); + exi_send_imm(chan, dev, &command, sizeof(command)); + exi_recv_imm(chan, dev, &id, sizeof(id)); + exi_unselect(chan); + + if (id == 0 || id == 0xffffffff) { + continue; + } + + eaa.eaa_id = id; + eaa.eaa_chan = chan; + eaa.eaa_device = dev; + + ch->ch_child[dev] = config_found(self, &eaa, exi_print, + CFARGS(.submatch = config_stdsubmatch, + .locators = locs)); + } + } + + return 0; +} + +static int +exi_print(void *aux, const char *pnp) +{ + struct exi_attach_args *eaa = aux; + + if (pnp != NULL) { + aprint_normal("EXI device 0x%08x at %s", eaa->eaa_id, pnp); + } + + aprint_normal(" addr %u-%u", eaa->eaa_chan, eaa->eaa_device); + + return UNCONF; +} + +void +exi_select(uint8_t chan, uint8_t dev) +{ + struct exi_channel *ch; + uint32_t val; + + ASSERT_CHAN_VALID(chan); + ASSERT_DEV_VALID(dev); + + ch = &exi_softc->sc_chan[chan]; + mutex_enter(&ch->ch_lock); + + val = RD4(exi_softc, EXI_CSR(chan)); + val &= ~EXI_CSR_CS; + val |= __SHIFTIN(__BIT(dev), EXI_CSR_CS); + WR4(exi_softc, EXI_CSR(chan), val); +} + +void +exi_unselect(uint8_t chan) +{ + struct exi_channel *ch; + uint32_t val; + + ASSERT_CHAN_VALID(chan); + + ch = &exi_softc->sc_chan[chan]; + + val = RD4(exi_softc, EXI_CSR(chan)); + val &= ~EXI_CSR_CS; + WR4(exi_softc, EXI_CSR(chan), val); + + mutex_exit(&ch->ch_lock); +} + +static void +exi_wait(uint8_t chan) +{ + uint32_t val; + + ASSERT_CHAN_VALID(chan); + + do { + val = RD4(exi_softc, EXI_CR(chan)); + } while ((val & EXI_CR_TSTART) != 0); +} + +void +exi_send_imm(uint8_t chan, uint8_t dev, const void *data, size_t datalen) +{ + struct exi_channel *ch; + uint32_t val = 0; + + ASSERT_CHAN_VALID(chan); + ASSERT_DEV_VALID(dev); + ASSERT_LEN_VALID(datalen); + + ch = &exi_softc->sc_chan[chan]; + KASSERT(mutex_owned(&ch->ch_lock)); + + switch (datalen) { + case 1: + val = *(const uint8_t *)data << 24; + break; + case 2: + val = *(const uint16_t *)data << 16; + break; + case 4: + val = *(const uint32_t *)data; + break; + } + + WR4(exi_softc, EXI_DATA(chan), val); + WR4(exi_softc, EXI_CR(chan), + EXI_CR_TSTART | EXI_CR_RW_WRITE | + __SHIFTIN(datalen - 1, EXI_CR_TLEN)); + exi_wait(chan); +} + +void +exi_recv_imm(uint8_t chan, uint8_t dev, void *data, size_t datalen) +{ + struct exi_channel *ch; + uint32_t val; + + ASSERT_CHAN_VALID(chan); + ASSERT_DEV_VALID(dev); + ASSERT_LEN_VALID(datalen); + + ch = &exi_softc->sc_chan[chan]; + KASSERT(mutex_owned(&ch->ch_lock)); + + WR4(exi_softc, EXI_CR(chan), + EXI_CR_TSTART | EXI_CR_RW_READ | + __SHIFTIN(datalen - 1, EXI_CR_TLEN)); + exi_wait(chan); + val = RD4(exi_softc, EXI_DATA(chan)); + + switch (datalen) { + case 1: + *(uint8_t *)data = val >> 24; + break; + case 2: + *(uint16_t *)data = val >> 16; + break; + case 4: + *(uint32_t *)data = val; + break; + } +} + +void +exi_recv_dma(uint8_t chan, uint8_t dev, void *data, size_t datalen) +{ + struct exi_channel *ch; + int error; + + ASSERT_CHAN_VALID(chan); + ASSERT_DEV_VALID(dev); + KASSERT((datalen & 0x1f) == 0); + + ch = &exi_softc->sc_chan[chan]; + KASSERT(mutex_owned(&ch->ch_lock)); + + error = bus_dmamap_load(exi_softc->sc_dmat, ch->ch_dmamap, + data, datalen, NULL, BUS_DMA_WAITOK); + if (error != 0) { + device_printf(exi_softc->sc_dev, "can't load DMA handle: %d\n", + error); + return; + } + + KASSERT((ch->ch_dmamap->dm_segs[0].ds_addr & 0x1f) == 0); + + bus_dmamap_sync(exi_softc->sc_dmat, ch->ch_dmamap, 0, datalen, + BUS_DMASYNC_PREREAD); + + WR4(exi_softc, EXI_MAR(chan), ch->ch_dmamap->dm_segs[0].ds_addr); + WR4(exi_softc, EXI_LENGTH(chan), datalen); + WR4(exi_softc, EXI_CR(chan), + EXI_CR_TSTART | EXI_CR_RW_READ | EXI_CR_DMA); + exi_wait(chan); + + bus_dmamap_sync(exi_softc->sc_dmat, ch->ch_dmamap, 0, datalen, + BUS_DMASYNC_POSTREAD); + + bus_dmamap_unload(exi_softc->sc_dmat, ch->ch_dmamap); +} diff --git a/sys/arch/evbppc/wii/dev/exi.h b/sys/arch/evbppc/wii/dev/exi.h new file mode 100644 index 000000000000..7b1709796522 --- /dev/null +++ b/sys/arch/evbppc/wii/dev/exi.h @@ -0,0 +1,44 @@ +/* $NetBSD: exi.h,v 1.1 2024/01/25 11:47:53 jmcneill Exp $ */ + +/*- + * Copyright (c) 2024 Jared McNeill + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _WII_DEV_EXI_H_ +#define _WII_DEV_EXI_H_ + +struct exi_attach_args { + uint32_t eaa_id; + uint8_t eaa_chan; + uint8_t eaa_device; +}; + +void exi_select(uint8_t, uint8_t); +void exi_unselect(uint8_t); +void exi_send_imm(uint8_t, uint8_t, const void *, size_t); +void exi_recv_imm(uint8_t, uint8_t, void *, size_t); +void exi_recv_dma(uint8_t, uint8_t, void *, size_t); + +#endif /* _WII_DEV_EXI_H_ */ diff --git a/sys/arch/evbppc/wii/dev/rtcsram.c b/sys/arch/evbppc/wii/dev/rtcsram.c new file mode 100644 index 000000000000..7d6f9ee619de --- /dev/null +++ b/sys/arch/evbppc/wii/dev/rtcsram.c @@ -0,0 +1,177 @@ +/* $NetBSD: rtcsram.c,v 1.1 2024/01/25 11:47:53 jmcneill Exp $ */ + +/*- + * Copyright (c) 2024 Jared McNeill + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: rtcsram.c,v 1.1 2024/01/25 11:47:53 jmcneill Exp $"); + +#include +#include +#include +#include +#include + +#include + +#include "exi.h" + +#define WII_RTCSRAM_ID 0xfffff308 + +#define RTC_BASE 0x20000000 +#define SRAM_BASE 0x20000100 + +#define WRITE_OFFSET 0x80000000 + +struct rtcsram_sram { + uint16_t checksum[2]; + uint16_t ead[2]; + int32_t counter_bias; + int8_t display_offset_h; + uint8_t ntd; + uint8_t language; + uint8_t flags; + uint16_t flash_id[12]; + uint32_t wireless_keyboard_id; + uint32_t wireless_pad_id[2]; + uint8_t last_dvd_errorcode; + uint8_t padding1; + uint16_t flash_id_checksum[2]; + uint16_t padding2; +} __aligned(32); +CTASSERT(sizeof(struct rtcsram_sram) == 64); + +struct rtcsram_softc { + struct todr_chip_handle sc_todr; + + uint8_t sc_chan; + uint8_t sc_device; + + struct rtcsram_sram sc_sram; +}; + +static int rtcsram_match(device_t, cfdata_t, void *); +static void rtcsram_attach(device_t, device_t, void *); + +static uint32_t rtcsram_read_4(struct rtcsram_softc *, uint32_t); +static void rtcsram_write_4(struct rtcsram_softc *, uint32_t, uint32_t); +static void rtcsram_read_buf(struct rtcsram_softc *, uint32_t, void *, + size_t); + +static int rtcsram_gettime(todr_chip_handle_t, struct timeval *); +static int rtcsram_settime(todr_chip_handle_t, struct timeval *); + +CFATTACH_DECL_NEW(rtcsram, sizeof(struct rtcsram_softc), + rtcsram_match, rtcsram_attach, NULL, NULL); + +static int +rtcsram_match(device_t parent, cfdata_t cf, void *aux) +{ + struct exi_attach_args * const eaa = aux; + + return eaa->eaa_id == WII_RTCSRAM_ID; +} + +static void +rtcsram_attach(device_t parent, device_t self, void *aux) +{ + struct rtcsram_softc * const sc = device_private(self); + struct exi_attach_args * const eaa = aux; + + aprint_naive("\n"); + aprint_normal(": RTC/SRAM\n"); + + sc->sc_chan = eaa->eaa_chan; + sc->sc_device = eaa->eaa_device; + + /* Read RTC counter bias from SRAM. */ + rtcsram_read_buf(sc, SRAM_BASE, &sc->sc_sram, sizeof(sc->sc_sram)); + aprint_debug_dev(self, "counter bias %d\n", sc->sc_sram.counter_bias); + hexdump(aprint_debug, device_xname(self), &sc->sc_sram, + sizeof(sc->sc_sram)); + + sc->sc_todr.cookie = sc; + sc->sc_todr.todr_gettime = rtcsram_gettime; + sc->sc_todr.todr_settime = rtcsram_settime; + todr_attach(&sc->sc_todr); +} + +static uint32_t +rtcsram_read_4(struct rtcsram_softc *sc, uint32_t offset) +{ + uint32_t val; + + exi_select(sc->sc_chan, sc->sc_device); + exi_send_imm(sc->sc_chan, sc->sc_device, &offset, sizeof(offset)); + exi_recv_imm(sc->sc_chan, sc->sc_device, &val, sizeof(val)); + exi_unselect(sc->sc_chan); + + return val; +} + +static void +rtcsram_write_4(struct rtcsram_softc *sc, uint32_t offset, uint32_t val) +{ + offset |= WRITE_OFFSET; + + exi_select(sc->sc_chan, sc->sc_device); + exi_send_imm(sc->sc_chan, sc->sc_device, &offset, sizeof(offset)); + exi_send_imm(sc->sc_chan, sc->sc_device, &val, sizeof(val)); + exi_unselect(sc->sc_chan); +} + +static void +rtcsram_read_buf(struct rtcsram_softc *sc, uint32_t offset, void *data, + size_t datalen) +{ + exi_select(sc->sc_chan, sc->sc_device); + exi_send_imm(sc->sc_chan, sc->sc_device, &offset, sizeof(offset)); + exi_recv_dma(sc->sc_chan, sc->sc_device, data, datalen); + exi_unselect(sc->sc_chan); +} + +static int +rtcsram_gettime(todr_chip_handle_t ch, struct timeval *tv) +{ + struct rtcsram_softc * const sc = ch->cookie; + uint32_t val; + + val = rtcsram_read_4(sc, RTC_BASE); + tv->tv_sec = (uint64_t)val + sc->sc_sram.counter_bias; + tv->tv_usec = 0; + + return 0; +} + +static int +rtcsram_settime(todr_chip_handle_t ch, struct timeval *tv) +{ + struct rtcsram_softc * const sc = ch->cookie; + + rtcsram_write_4(sc, RTC_BASE, tv->tv_sec - sc->sc_sram.counter_bias); + + return 0; +} diff --git a/sys/arch/evbppc/wii/mainbus.c b/sys/arch/evbppc/wii/mainbus.c index e403da833f98..511196caa4cb 100644 --- a/sys/arch/evbppc/wii/mainbus.c +++ b/sys/arch/evbppc/wii/mainbus.c @@ -1,4 +1,4 @@ -/* $NetBSD: mainbus.c,v 1.2 2024/01/22 21:28:15 jmcneill Exp $ */ +/* $NetBSD: mainbus.c,v 1.3 2024/01/25 11:47:53 jmcneill Exp $ */ /* * Copyright (c) 2002, 2024 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.2 2024/01/22 21:28:15 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.3 2024/01/25 11:47:53 jmcneill Exp $"); #include #include @@ -102,6 +102,11 @@ mainbus_attach(device_t parent, device_t self, void *aux) maa.maa_irq = MAINBUSCF_IRQ_DEFAULT; config_found(self, &maa, mainbus_print, CFARGS_NONE); + maa.maa_name = "exi"; + maa.maa_addr = EXI_BASE; + maa.maa_irq = PI_IRQ_EXI; + config_found(self, &maa, mainbus_print, CFARGS_NONE); + maa.maa_name = "hollywood"; maa.maa_addr = MAINBUSCF_ADDR_DEFAULT; maa.maa_irq = PI_IRQ_HOLLYWOOD;