#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sif.c,v 1.14 2025/12/24 20:37:04 andvar Exp $");
#include "debug_playstation2.h"
#include <sys/intr.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <playstation2/playstation2/sifbios.h>
#include <playstation2/ee/dmacvar.h>
#include <playstation2/ee/sifvar.h>
#ifdef SIF_DEBUG
int __spd_total_alloc;
int sif_debug = 1;
#define DPRINTF(fmt, args...) \
if (sif_debug) \
printf("%s: " fmt, __func__ , ##args)
#define DPRINTFN(n, arg) \
if (sif_debug > (n)) \
n printf("%s: " fmt, __func__ , ##args)
#else
#define DPRINTF(arg...) ((void)0)
#define DPRINTFN(n, arg...) ((void)0)
#endif
#define ROUND64(x) ((((u_int32_t)(x)) + 63) & ~64)
#define BCD_TO_DECIMAL(x) \
({ \
typeof(x) x_ = x; \
(((x_) >> 4) * 10 + ((x_) & 0xf)); \
})
#define MAJOR(x) BCD_TO_DECIMAL(((x) >> 8) & 0xff)
#define MINOR(x) BCD_TO_DECIMAL((x) & 0xff)
void
sif_init(void)
{
u_int32_t vers;
vers = sifbios_getver();
printf("PlayStation 2 SIF BIOS version %d.%d\n",
MAJOR(vers), MINOR(vers));
if (sifdma_init() < 0)
panic("SIFDMA");
if (sifcmd_init() < 0)
panic("SIFCMD");
dmac_intr_establish(D_CH5_SIF0, IPL_TTY, sifcmd_intr, 0);
if (sifrpc_init() < 0)
panic("SIFRPC");
if (iopmem_init() < 0)
panic("IOP Memory");
}
void
sif_exit(void)
{
sifrpc_exit();
sifcmd_exit();
dmac_intr_disestablish((void *)D_CH5_SIF0);
sifdma_exit();
}
int
iopdma_allocate_buffer(struct iopdma_segment *seg, size_t size)
{
seg->size = ROUND64(size);
seg->iop_paddr = iopmem_alloc(seg->size);
if (seg->iop_paddr == 0) {
printf("%s: can't allocate IOP memory.\n", __func__);
DPRINTF("request = %lu byte, current total = %#x\n",
size, __spd_total_alloc);
return (1);
}
seg->ee_vaddr = IOPPHYS_TO_EEKV(seg->iop_paddr);
#ifdef SIF_DEBUG
__spd_total_alloc += size;
#endif
DPRINTF("0x%08x+%#lx (total=%#x)\n", seg->iop_paddr, size,
__spd_total_alloc);
KDASSERT((seg->ee_vaddr & 63) == 0);
return (0);
}
void
iopdma_free_buffer(struct iopdma_segment *seg)
{
int ret __unused;
ret = iopmem_free(seg->iop_paddr);
#ifdef SIF_DEBUG
__spd_total_alloc -= seg->size;
#endif
DPRINTF("0x%08x (total=%#x, result=%d)\n", seg->iop_paddr,
__spd_total_alloc, ret);
}