MIPS patches queue
- Extract nanoMIPS, microMIPS, Code Compaction from translate.c - Allow PCI config accesses smaller than 32-bit on Bonito64 device - Fix migration of g364fb device on Jazz Magnum - Fix dp8393x PROM checksum on Jazz Magnum and Quadra 800 - Map the UART devices unconditionally on Jazz Magnum - Add functional test booting Linux on the Fuloong 2E -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmDfMnMACgkQ4+MsLN6t wN71nhAArpyoJ5mTkt54wAxZwxvqjWAyesvogV4pLIvOyNJmQcExY/Ly8Qb5dbDg 2PEhCpDU7GlT7oCfgh7O5KrEjnqVfmHQzzbvQ0Ygq9kL5hdjaSSlHB/yeirU7CR1 cMQXfj9kvRVa5Oayt3L+kiKgTA0f1vbGmnveiFxJKJupyVDtursstD3nSZCThSVL FWdFJbqLzvTY3cQqLBVq7jEnN7LzSYeYnq8Tvri0nuwoBwLJY382IljqsQZrGHzr Bbya3KFInMrQK5VAM0pOkfvPYXZmtJ8i8VuR6S+IdICiZ+61sknKRUq5z09/4NXA HaxarWO/fv07qd7q6Z2+i5Q6fiDrV4p2qfHeddM4Xwqvu8O98EPhaBE3veLOiNgr VxgkJFslI1gstje31qqvNjFxB+cOIBYjWTlIVu1xOuOKGWMjMT+9XcVLseweA2rT H/nTKnWTAiJ/mxT4KIv59SS0ZQa4QJ3CjYr26AcQ9YrJ9vCMay8rLPEn0iVlhB2H ZyW4Be84ynEvuAvvuWt1AXvFjT41Zqj4Px1M6Pa15e9eV6guiW1KV13Thb45gJqt LTQtoME83r3gUhQOcoZaowYh6ffCbjtW3eAcTZP3Zu7fOeBjSye+CvS9NJMtK3Vj 0/YjtqGPUvjNy4sR9VqkRRPMZpHftMTRILxaFm8Y5tlThkAydw0= =rR+B -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/philmd/tags/mips-20210702' into staging MIPS patches queue - Extract nanoMIPS, microMIPS, Code Compaction from translate.c - Allow PCI config accesses smaller than 32-bit on Bonito64 device - Fix migration of g364fb device on Jazz Magnum - Fix dp8393x PROM checksum on Jazz Magnum and Quadra 800 - Map the UART devices unconditionally on Jazz Magnum - Add functional test booting Linux on the Fuloong 2E # gpg: Signature made Fri 02 Jul 2021 16:36:19 BST # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full] # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * remotes/philmd/tags/mips-20210702: hw/mips/jazz: Map the UART devices unconditionally hw/mips/jazz: specify correct endian for dp8393x device hw/m68k/q800: fix PROM checksum and MAC address storage qemu/bitops.h: add bitrev8 implementation dp8393x: remove onboard PROM containing MAC address and checksum hw/m68k/q800: move PROM and checksum calculation from dp8393x device to board hw/mips/jazz: move PROM and checksum calculation from dp8393x device to board dp8393x: convert to trace-events dp8393x: checkpatch fixes g364fb: add VMStateDescription for G364SysBusState g364fb: use RAM memory region for framebuffer tests/acceptance: Test Linux on the Fuloong 2E machine hw/pci-host/bonito: Allow PCI config accesses smaller than 32-bit hw/pci-host/bonito: Trace PCI config accesses smaller than 32-bit target/mips: Extract nanoMIPS ISA translation routines target/mips: Extract the microMIPS ISA translation routines target/mips: Extract Code Compaction ASE translation routines target/mips: Add declarations for generic TCG helpers Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
711c0418c8
@ -246,6 +246,7 @@ K: ^Subject:.*(?i)mips
|
||||
MIPS TCG CPUs (nanoMIPS ISA)
|
||||
S: Orphan
|
||||
F: disas/nanomips.*
|
||||
F: target/mips/tcg/*nanomips*
|
||||
|
||||
NiosII TCG CPUs
|
||||
M: Chris Wulff <crwulff@gmail.com>
|
||||
@ -1177,6 +1178,7 @@ F: hw/isa/vt82c686.c
|
||||
F: hw/pci-host/bonito.c
|
||||
F: hw/usb/vt82c686-uhci-pci.c
|
||||
F: include/hw/isa/vt82c686.h
|
||||
F: tests/acceptance/machine_mips_fuloong2e.py
|
||||
|
||||
Loongson-3 virtual platforms
|
||||
M: Huacai Chen <chenhuacai@kernel.org>
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "hw/hw.h"
|
||||
#include "hw/irq.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/module.h"
|
||||
#include "ui/console.h"
|
||||
@ -33,7 +34,6 @@
|
||||
|
||||
typedef struct G364State {
|
||||
/* hardware */
|
||||
uint8_t *vram;
|
||||
uint32_t vram_size;
|
||||
qemu_irq irq;
|
||||
MemoryRegion mem_vram;
|
||||
@ -125,7 +125,7 @@ static void g364fb_draw_graphic8(G364State *s)
|
||||
xcursor = ycursor = -65;
|
||||
}
|
||||
|
||||
vram = s->vram + s->top_of_screen;
|
||||
vram = memory_region_get_ram_ptr(&s->mem_vram) + s->top_of_screen;
|
||||
/* XXX: out of range in vram? */
|
||||
data_display = dd = surface_data(surface);
|
||||
snap = memory_region_snapshot_and_clear_dirty(&s->mem_vram, 0, s->vram_size,
|
||||
@ -274,6 +274,8 @@ static inline void g364fb_invalidate_display(void *opaque)
|
||||
|
||||
static void g364fb_reset(G364State *s)
|
||||
{
|
||||
uint8_t *vram = memory_region_get_ram_ptr(&s->mem_vram);
|
||||
|
||||
qemu_irq_lower(s->irq);
|
||||
|
||||
memset(s->color_palette, 0, sizeof(s->color_palette));
|
||||
@ -283,7 +285,7 @@ static void g364fb_reset(G364State *s)
|
||||
s->ctla = 0;
|
||||
s->top_of_screen = 0;
|
||||
s->width = s->height = 0;
|
||||
memset(s->vram, 0, s->vram_size);
|
||||
memset(vram, 0, s->vram_size);
|
||||
g364fb_invalidate_display(s);
|
||||
}
|
||||
|
||||
@ -450,11 +452,10 @@ static int g364fb_post_load(void *opaque, int version_id)
|
||||
|
||||
static const VMStateDescription vmstate_g364fb = {
|
||||
.name = "g364fb",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.version_id = 2,
|
||||
.minimum_version_id = 2,
|
||||
.post_load = g364fb_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_VBUFFER_UINT32(vram, G364State, 1, NULL, vram_size),
|
||||
VMSTATE_BUFFER_UNSAFE(color_palette, G364State, 0, 256 * 3),
|
||||
VMSTATE_BUFFER_UNSAFE(cursor_palette, G364State, 0, 9),
|
||||
VMSTATE_UINT16_ARRAY(cursor, G364State, 512),
|
||||
@ -474,15 +475,12 @@ static const GraphicHwOps g364fb_ops = {
|
||||
|
||||
static void g364fb_init(DeviceState *dev, G364State *s)
|
||||
{
|
||||
s->vram = g_malloc0(s->vram_size);
|
||||
|
||||
s->con = graphic_console_init(dev, 0, &g364fb_ops, s);
|
||||
|
||||
memory_region_init_io(&s->mem_ctrl, OBJECT(dev), &g364fb_ctrl_ops, s,
|
||||
"ctrl", 0x180000);
|
||||
memory_region_init_ram_ptr(&s->mem_vram, NULL, "vram",
|
||||
s->vram_size, s->vram);
|
||||
vmstate_register_ram(&s->mem_vram, dev);
|
||||
memory_region_init_ram(&s->mem_vram, NULL, "g364fb.vram", s->vram_size,
|
||||
&error_fatal);
|
||||
memory_region_set_log(&s->mem_vram, true, DIRTY_MEMORY_VGA);
|
||||
}
|
||||
|
||||
@ -519,6 +517,16 @@ static Property g364fb_sysbus_properties[] = {
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_g364fb_sysbus = {
|
||||
.name = "g364fb-sysbus",
|
||||
.version_id = 2,
|
||||
.minimum_version_id = 2,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_STRUCT(g364, G364SysBusState, 2, vmstate_g364fb, G364State),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static void g364fb_sysbus_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
@ -527,7 +535,7 @@ static void g364fb_sysbus_class_init(ObjectClass *klass, void *data)
|
||||
set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
|
||||
dc->desc = "G364 framebuffer";
|
||||
dc->reset = g364fb_sysbus_reset;
|
||||
dc->vmsd = &vmstate_g364fb;
|
||||
dc->vmsd = &vmstate_g364fb_sysbus;
|
||||
device_class_set_props(dc, g364fb_sysbus_properties);
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,8 @@
|
||||
#define NUBUS_SUPER_SLOT_BASE 0x60000000
|
||||
#define NUBUS_SLOT_BASE 0xf0000000
|
||||
|
||||
#define SONIC_PROM_SIZE 0x1000
|
||||
|
||||
/*
|
||||
* the video base, whereas it a Nubus address,
|
||||
* is needed by the kernel to have early display and
|
||||
@ -211,8 +213,10 @@ static void q800_init(MachineState *machine)
|
||||
int32_t initrd_size;
|
||||
MemoryRegion *rom;
|
||||
MemoryRegion *io;
|
||||
MemoryRegion *dp8393x_prom = g_new(MemoryRegion, 1);
|
||||
uint8_t *prom;
|
||||
const int io_slice_nb = (IO_SIZE / IO_SLICE) - 1;
|
||||
int i;
|
||||
int i, checksum;
|
||||
ram_addr_t ram_size = machine->ram_size;
|
||||
const char *kernel_filename = machine->kernel_filename;
|
||||
const char *initrd_filename = machine->initrd_filename;
|
||||
@ -319,9 +323,22 @@ static void q800_init(MachineState *machine)
|
||||
sysbus = SYS_BUS_DEVICE(dev);
|
||||
sysbus_realize_and_unref(sysbus, &error_fatal);
|
||||
sysbus_mmio_map(sysbus, 0, SONIC_BASE);
|
||||
sysbus_mmio_map(sysbus, 1, SONIC_PROM_BASE);
|
||||
sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(glue, 2));
|
||||
|
||||
memory_region_init_rom(dp8393x_prom, NULL, "dp8393x-q800.prom",
|
||||
SONIC_PROM_SIZE, &error_fatal);
|
||||
memory_region_add_subregion(get_system_memory(), SONIC_PROM_BASE,
|
||||
dp8393x_prom);
|
||||
|
||||
/* Add MAC address with valid checksum to PROM */
|
||||
prom = memory_region_get_ram_ptr(dp8393x_prom);
|
||||
checksum = 0;
|
||||
for (i = 0; i < 6; i++) {
|
||||
prom[i] = bitrev8(nd_table[0].macaddr.a[i]);
|
||||
checksum ^= prom[i];
|
||||
}
|
||||
prom[7] = 0xff - checksum;
|
||||
|
||||
/* SCC */
|
||||
|
||||
dev = qdev_new(TYPE_ESCC);
|
||||
|
@ -119,12 +119,14 @@ static const MemoryRegionOps dma_dummy_ops = {
|
||||
#define MAGNUM_BIOS_SIZE \
|
||||
(BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX)
|
||||
|
||||
#define SONIC_PROM_SIZE 0x1000
|
||||
|
||||
static void mips_jazz_init(MachineState *machine,
|
||||
enum jazz_model_e jazz_model)
|
||||
{
|
||||
MemoryRegion *address_space = get_system_memory();
|
||||
char *filename;
|
||||
int bios_size, n;
|
||||
int bios_size, n, big_endian;
|
||||
Clock *cpuclk;
|
||||
MIPSCPU *cpu;
|
||||
MIPSCPUClass *mcc;
|
||||
@ -137,6 +139,7 @@ static void mips_jazz_init(MachineState *machine,
|
||||
MemoryRegion *rtc = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *i8042 = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *dma_dummy = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *dp8393x_prom = g_new(MemoryRegion, 1);
|
||||
NICInfo *nd;
|
||||
DeviceState *dev, *rc4030;
|
||||
SysBusDevice *sysbus;
|
||||
@ -155,6 +158,12 @@ static void mips_jazz_init(MachineState *machine,
|
||||
[JAZZ_PICA61] = {33333333, 4},
|
||||
};
|
||||
|
||||
#ifdef TARGET_WORDS_BIGENDIAN
|
||||
big_endian = 1;
|
||||
#else
|
||||
big_endian = 0;
|
||||
#endif
|
||||
|
||||
if (machine->ram_size > 256 * MiB) {
|
||||
error_report("RAM size more than 256Mb is not supported");
|
||||
exit(EXIT_FAILURE);
|
||||
@ -228,6 +237,10 @@ static void mips_jazz_init(MachineState *machine,
|
||||
NULL, "dummy_dma", 0x1000);
|
||||
memory_region_add_subregion(address_space, 0x8000d000, dma_dummy);
|
||||
|
||||
memory_region_init_rom(dp8393x_prom, NULL, "dp8393x-jazz.prom",
|
||||
SONIC_PROM_SIZE, &error_fatal);
|
||||
memory_region_add_subregion(address_space, 0x8000b000, dp8393x_prom);
|
||||
|
||||
/* ISA bus: IO space at 0x90000000, mem space at 0x91000000 */
|
||||
memory_region_init(isa_io, NULL, "isa-io", 0x00010000);
|
||||
memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000);
|
||||
@ -275,18 +288,33 @@ static void mips_jazz_init(MachineState *machine,
|
||||
nd->model = g_strdup("dp83932");
|
||||
}
|
||||
if (strcmp(nd->model, "dp83932") == 0) {
|
||||
int checksum, i;
|
||||
uint8_t *prom;
|
||||
|
||||
qemu_check_nic_model(nd, "dp83932");
|
||||
|
||||
dev = qdev_new("dp8393x");
|
||||
qdev_set_nic_properties(dev, nd);
|
||||
qdev_prop_set_uint8(dev, "it_shift", 2);
|
||||
qdev_prop_set_bit(dev, "big_endian", big_endian > 0);
|
||||
object_property_set_link(OBJECT(dev), "dma_mr",
|
||||
OBJECT(rc4030_dma_mr), &error_abort);
|
||||
sysbus = SYS_BUS_DEVICE(dev);
|
||||
sysbus_realize_and_unref(sysbus, &error_fatal);
|
||||
sysbus_mmio_map(sysbus, 0, 0x80001000);
|
||||
sysbus_mmio_map(sysbus, 1, 0x8000b000);
|
||||
sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 4));
|
||||
|
||||
/* Add MAC address with valid checksum to PROM */
|
||||
prom = memory_region_get_ram_ptr(dp8393x_prom);
|
||||
checksum = 0;
|
||||
for (i = 0; i < 6; i++) {
|
||||
prom[i] = nd->macaddr.a[i];
|
||||
checksum += prom[i];
|
||||
if (checksum > 0xff) {
|
||||
checksum = (checksum + 1) & 0xff;
|
||||
}
|
||||
}
|
||||
prom[7] = 0xff - checksum;
|
||||
break;
|
||||
} else if (is_help_option(nd->model)) {
|
||||
error_report("Supported NICs: dp83932");
|
||||
@ -333,16 +361,12 @@ static void mips_jazz_init(MachineState *machine,
|
||||
memory_region_add_subregion(address_space, 0x80005000, i8042);
|
||||
|
||||
/* Serial ports */
|
||||
if (serial_hd(0)) {
|
||||
serial_mm_init(address_space, 0x80006000, 0,
|
||||
qdev_get_gpio_in(rc4030, 8), 8000000 / 16,
|
||||
serial_hd(0), DEVICE_NATIVE_ENDIAN);
|
||||
}
|
||||
if (serial_hd(1)) {
|
||||
serial_mm_init(address_space, 0x80007000, 0,
|
||||
qdev_get_gpio_in(rc4030, 9), 8000000 / 16,
|
||||
serial_hd(1), DEVICE_NATIVE_ENDIAN);
|
||||
}
|
||||
serial_mm_init(address_space, 0x80006000, 0,
|
||||
qdev_get_gpio_in(rc4030, 8), 8000000 / 16,
|
||||
serial_hd(0), DEVICE_NATIVE_ENDIAN);
|
||||
serial_mm_init(address_space, 0x80007000, 0,
|
||||
qdev_get_gpio_in(rc4030, 9), 8000000 / 16,
|
||||
serial_hd(1), DEVICE_NATIVE_ENDIAN);
|
||||
|
||||
/* Parallel port */
|
||||
if (parallel_hds[0])
|
||||
|
302
hw/net/dp8393x.c
302
hw/net/dp8393x.c
@ -28,15 +28,9 @@
|
||||
#include "qemu/timer.h"
|
||||
#include <zlib.h>
|
||||
#include "qom/object.h"
|
||||
#include "trace.h"
|
||||
|
||||
//#define DEBUG_SONIC
|
||||
|
||||
#define SONIC_PROM_SIZE 0x1000
|
||||
|
||||
#ifdef DEBUG_SONIC
|
||||
#define DPRINTF(fmt, ...) \
|
||||
do { printf("sonic: " fmt , ## __VA_ARGS__); } while (0)
|
||||
static const char* reg_names[] = {
|
||||
static const char *reg_names[] = {
|
||||
"CR", "DCR", "RCR", "TCR", "IMR", "ISR", "UTDA", "CTDA",
|
||||
"TPS", "TFC", "TSA0", "TSA1", "TFS", "URDA", "CRDA", "CRBA0",
|
||||
"CRBA1", "RBWC0", "RBWC1", "EOBC", "URRA", "RSA", "REA", "RRP",
|
||||
@ -45,12 +39,6 @@ static const char* reg_names[] = {
|
||||
"SR", "WT0", "WT1", "RSC", "CRCT", "FAET", "MPT", "MDT",
|
||||
"0x30", "0x31", "0x32", "0x33", "0x34", "0x35", "0x36", "0x37",
|
||||
"0x38", "0x39", "0x3a", "0x3b", "0x3c", "0x3d", "0x3e", "DCR2" };
|
||||
#else
|
||||
#define DPRINTF(fmt, ...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define SONIC_ERROR(fmt, ...) \
|
||||
do { printf("sonic ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0)
|
||||
|
||||
#define SONIC_CR 0x00
|
||||
#define SONIC_DCR 0x01
|
||||
@ -161,15 +149,12 @@ struct dp8393xState {
|
||||
bool big_endian;
|
||||
bool last_rba_is_full;
|
||||
qemu_irq irq;
|
||||
#ifdef DEBUG_SONIC
|
||||
int irq_level;
|
||||
#endif
|
||||
QEMUTimer *watchdog;
|
||||
int64_t wt_last_update;
|
||||
NICConf conf;
|
||||
NICState *nic;
|
||||
MemoryRegion mmio;
|
||||
MemoryRegion prom;
|
||||
|
||||
/* Registers */
|
||||
uint8_t cam[16][6];
|
||||
@ -185,7 +170,8 @@ struct dp8393xState {
|
||||
AddressSpace as;
|
||||
};
|
||||
|
||||
/* Accessor functions for values which are formed by
|
||||
/*
|
||||
* Accessor functions for values which are formed by
|
||||
* concatenating two 16 bit device registers. By putting these
|
||||
* in their own functions with a uint32_t return type we avoid the
|
||||
* pitfall of implicit sign extension where ((x << 16) | y) is a
|
||||
@ -269,16 +255,14 @@ static void dp8393x_update_irq(dp8393xState *s)
|
||||
{
|
||||
int level = (s->regs[SONIC_IMR] & s->regs[SONIC_ISR]) ? 1 : 0;
|
||||
|
||||
#ifdef DEBUG_SONIC
|
||||
if (level != s->irq_level) {
|
||||
s->irq_level = level;
|
||||
if (level) {
|
||||
DPRINTF("raise irq, isr is 0x%04x\n", s->regs[SONIC_ISR]);
|
||||
trace_dp8393x_raise_irq(s->regs[SONIC_ISR]);
|
||||
} else {
|
||||
DPRINTF("lower irq\n");
|
||||
trace_dp8393x_lower_irq();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
qemu_set_irq(s->irq, level);
|
||||
}
|
||||
@ -301,9 +285,9 @@ static void dp8393x_do_load_cam(dp8393xState *s)
|
||||
s->cam[index][3] = dp8393x_get(s, width, 2) >> 8;
|
||||
s->cam[index][4] = dp8393x_get(s, width, 3) & 0xff;
|
||||
s->cam[index][5] = dp8393x_get(s, width, 3) >> 8;
|
||||
DPRINTF("load cam[%d] with %02x%02x%02x%02x%02x%02x\n", index,
|
||||
s->cam[index][0], s->cam[index][1], s->cam[index][2],
|
||||
s->cam[index][3], s->cam[index][4], s->cam[index][5]);
|
||||
trace_dp8393x_load_cam(index, s->cam[index][0], s->cam[index][1],
|
||||
s->cam[index][2], s->cam[index][3],
|
||||
s->cam[index][4], s->cam[index][5]);
|
||||
/* Move to next entry */
|
||||
s->regs[SONIC_CDC]--;
|
||||
s->regs[SONIC_CDP] += size;
|
||||
@ -314,7 +298,7 @@ static void dp8393x_do_load_cam(dp8393xState *s)
|
||||
address_space_read(&s->as, dp8393x_cdp(s),
|
||||
MEMTXATTRS_UNSPECIFIED, s->data, size);
|
||||
s->regs[SONIC_CE] = dp8393x_get(s, width, 0);
|
||||
DPRINTF("load cam done. cam enable mask 0x%04x\n", s->regs[SONIC_CE]);
|
||||
trace_dp8393x_load_cam_done(s->regs[SONIC_CE]);
|
||||
|
||||
/* Done */
|
||||
s->regs[SONIC_CR] &= ~SONIC_CR_LCAM;
|
||||
@ -337,9 +321,8 @@ static void dp8393x_do_read_rra(dp8393xState *s)
|
||||
s->regs[SONIC_CRBA1] = dp8393x_get(s, width, 1);
|
||||
s->regs[SONIC_RBWC0] = dp8393x_get(s, width, 2);
|
||||
s->regs[SONIC_RBWC1] = dp8393x_get(s, width, 3);
|
||||
DPRINTF("CRBA0/1: 0x%04x/0x%04x, RBWC0/1: 0x%04x/0x%04x\n",
|
||||
s->regs[SONIC_CRBA0], s->regs[SONIC_CRBA1],
|
||||
s->regs[SONIC_RBWC0], s->regs[SONIC_RBWC1]);
|
||||
trace_dp8393x_read_rra_regs(s->regs[SONIC_CRBA0], s->regs[SONIC_CRBA1],
|
||||
s->regs[SONIC_RBWC0], s->regs[SONIC_RBWC1]);
|
||||
|
||||
/* Go to next entry */
|
||||
s->regs[SONIC_RRP] += size;
|
||||
@ -350,8 +333,7 @@ static void dp8393x_do_read_rra(dp8393xState *s)
|
||||
}
|
||||
|
||||
/* Warn the host if CRBA now has the last available resource */
|
||||
if (s->regs[SONIC_RRP] == s->regs[SONIC_RWP])
|
||||
{
|
||||
if (s->regs[SONIC_RRP] == s->regs[SONIC_RWP]) {
|
||||
s->regs[SONIC_ISR] |= SONIC_ISR_RBE;
|
||||
dp8393x_update_irq(s);
|
||||
}
|
||||
@ -364,7 +346,8 @@ static void dp8393x_do_software_reset(dp8393xState *s)
|
||||
{
|
||||
timer_del(s->watchdog);
|
||||
|
||||
s->regs[SONIC_CR] &= ~(SONIC_CR_LCAM | SONIC_CR_RRRA | SONIC_CR_TXP | SONIC_CR_HTX);
|
||||
s->regs[SONIC_CR] &= ~(SONIC_CR_LCAM | SONIC_CR_RRRA | SONIC_CR_TXP |
|
||||
SONIC_CR_HTX);
|
||||
s->regs[SONIC_CR] |= SONIC_CR_RST | SONIC_CR_RXDIS;
|
||||
}
|
||||
|
||||
@ -443,7 +426,7 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
|
||||
/* Read memory */
|
||||
size = sizeof(uint16_t) * 6 * width;
|
||||
s->regs[SONIC_TTDA] = s->regs[SONIC_CTDA];
|
||||
DPRINTF("Transmit packet at %08x\n", dp8393x_ttda(s));
|
||||
trace_dp8393x_transmit_packet(dp8393x_ttda(s));
|
||||
address_space_read(&s->as, dp8393x_ttda(s) + sizeof(uint16_t) * width,
|
||||
MEMTXATTRS_UNSPECIFIED, s->data, size);
|
||||
tx_len = 0;
|
||||
@ -490,13 +473,15 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
|
||||
|
||||
/* Handle Ethernet checksum */
|
||||
if (!(s->regs[SONIC_TCR] & SONIC_TCR_CRCI)) {
|
||||
/* Don't append FCS there, to look like slirp packets
|
||||
* which don't have one */
|
||||
/*
|
||||
* Don't append FCS there, to look like slirp packets
|
||||
* which don't have one
|
||||
*/
|
||||
} else {
|
||||
/* Remove existing FCS */
|
||||
tx_len -= 4;
|
||||
if (tx_len < 0) {
|
||||
SONIC_ERROR("tx_len is %d\n", tx_len);
|
||||
trace_dp8393x_transmit_txlen_error(tx_len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -558,26 +543,34 @@ static void dp8393x_do_command(dp8393xState *s, uint16_t command)
|
||||
|
||||
s->regs[SONIC_CR] |= (command & SONIC_CR_MASK);
|
||||
|
||||
if (command & SONIC_CR_HTX)
|
||||
if (command & SONIC_CR_HTX) {
|
||||
dp8393x_do_halt_transmission(s);
|
||||
if (command & SONIC_CR_TXP)
|
||||
}
|
||||
if (command & SONIC_CR_TXP) {
|
||||
dp8393x_do_transmit_packets(s);
|
||||
if (command & SONIC_CR_RXDIS)
|
||||
}
|
||||
if (command & SONIC_CR_RXDIS) {
|
||||
dp8393x_do_receiver_disable(s);
|
||||
if (command & SONIC_CR_RXEN)
|
||||
}
|
||||
if (command & SONIC_CR_RXEN) {
|
||||
dp8393x_do_receiver_enable(s);
|
||||
if (command & SONIC_CR_STP)
|
||||
}
|
||||
if (command & SONIC_CR_STP) {
|
||||
dp8393x_do_stop_timer(s);
|
||||
if (command & SONIC_CR_ST)
|
||||
}
|
||||
if (command & SONIC_CR_ST) {
|
||||
dp8393x_do_start_timer(s);
|
||||
if (command & SONIC_CR_RST)
|
||||
}
|
||||
if (command & SONIC_CR_RST) {
|
||||
dp8393x_do_software_reset(s);
|
||||
}
|
||||
if (command & SONIC_CR_RRRA) {
|
||||
dp8393x_do_read_rra(s);
|
||||
s->regs[SONIC_CR] &= ~SONIC_CR_RRRA;
|
||||
}
|
||||
if (command & SONIC_CR_LCAM)
|
||||
if (command & SONIC_CR_LCAM) {
|
||||
dp8393x_do_load_cam(s);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t dp8393x_read(void *opaque, hwaddr addr, unsigned int size)
|
||||
@ -587,27 +580,27 @@ static uint64_t dp8393x_read(void *opaque, hwaddr addr, unsigned int size)
|
||||
uint16_t val = 0;
|
||||
|
||||
switch (reg) {
|
||||
/* Update data before reading it */
|
||||
case SONIC_WT0:
|
||||
case SONIC_WT1:
|
||||
dp8393x_update_wt_regs(s);
|
||||
val = s->regs[reg];
|
||||
break;
|
||||
/* Accept read to some registers only when in reset mode */
|
||||
case SONIC_CAP2:
|
||||
case SONIC_CAP1:
|
||||
case SONIC_CAP0:
|
||||
if (s->regs[SONIC_CR] & SONIC_CR_RST) {
|
||||
val = s->cam[s->regs[SONIC_CEP] & 0xf][2* (SONIC_CAP0 - reg) + 1] << 8;
|
||||
val |= s->cam[s->regs[SONIC_CEP] & 0xf][2* (SONIC_CAP0 - reg)];
|
||||
}
|
||||
break;
|
||||
/* All other registers have no special contrainst */
|
||||
default:
|
||||
val = s->regs[reg];
|
||||
/* Update data before reading it */
|
||||
case SONIC_WT0:
|
||||
case SONIC_WT1:
|
||||
dp8393x_update_wt_regs(s);
|
||||
val = s->regs[reg];
|
||||
break;
|
||||
/* Accept read to some registers only when in reset mode */
|
||||
case SONIC_CAP2:
|
||||
case SONIC_CAP1:
|
||||
case SONIC_CAP0:
|
||||
if (s->regs[SONIC_CR] & SONIC_CR_RST) {
|
||||
val = s->cam[s->regs[SONIC_CEP] & 0xf][2 * (SONIC_CAP0 - reg) + 1] << 8;
|
||||
val |= s->cam[s->regs[SONIC_CEP] & 0xf][2 * (SONIC_CAP0 - reg)];
|
||||
}
|
||||
break;
|
||||
/* All other registers have no special contraints */
|
||||
default:
|
||||
val = s->regs[reg];
|
||||
}
|
||||
|
||||
DPRINTF("read 0x%04x from reg %s\n", val, reg_names[reg]);
|
||||
trace_dp8393x_read(reg, reg_names[reg], val, size);
|
||||
|
||||
return s->big_endian ? val << 16 : val;
|
||||
}
|
||||
@ -619,78 +612,78 @@ static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
int reg = addr >> s->it_shift;
|
||||
uint32_t val = s->big_endian ? data >> 16 : data;
|
||||
|
||||
DPRINTF("write 0x%04x to reg %s\n", (uint16_t)val, reg_names[reg]);
|
||||
trace_dp8393x_write(reg, reg_names[reg], val, size);
|
||||
|
||||
switch (reg) {
|
||||
/* Command register */
|
||||
case SONIC_CR:
|
||||
dp8393x_do_command(s, val);
|
||||
break;
|
||||
/* Prevent write to read-only registers */
|
||||
case SONIC_CAP2:
|
||||
case SONIC_CAP1:
|
||||
case SONIC_CAP0:
|
||||
case SONIC_SR:
|
||||
case SONIC_MDT:
|
||||
DPRINTF("writing to reg %d invalid\n", reg);
|
||||
break;
|
||||
/* Accept write to some registers only when in reset mode */
|
||||
case SONIC_DCR:
|
||||
if (s->regs[SONIC_CR] & SONIC_CR_RST) {
|
||||
s->regs[reg] = val & 0xbfff;
|
||||
} else {
|
||||
DPRINTF("writing to DCR invalid\n");
|
||||
}
|
||||
break;
|
||||
case SONIC_DCR2:
|
||||
if (s->regs[SONIC_CR] & SONIC_CR_RST) {
|
||||
s->regs[reg] = val & 0xf017;
|
||||
} else {
|
||||
DPRINTF("writing to DCR2 invalid\n");
|
||||
}
|
||||
break;
|
||||
/* 12 lower bytes are Read Only */
|
||||
case SONIC_TCR:
|
||||
s->regs[reg] = val & 0xf000;
|
||||
break;
|
||||
/* 9 lower bytes are Read Only */
|
||||
case SONIC_RCR:
|
||||
s->regs[reg] = val & 0xffe0;
|
||||
break;
|
||||
/* Ignore most significant bit */
|
||||
case SONIC_IMR:
|
||||
s->regs[reg] = val & 0x7fff;
|
||||
dp8393x_update_irq(s);
|
||||
break;
|
||||
/* Clear bits by writing 1 to them */
|
||||
case SONIC_ISR:
|
||||
val &= s->regs[reg];
|
||||
s->regs[reg] &= ~val;
|
||||
if (val & SONIC_ISR_RBE) {
|
||||
dp8393x_do_read_rra(s);
|
||||
}
|
||||
dp8393x_update_irq(s);
|
||||
break;
|
||||
/* The guest is required to store aligned pointers here */
|
||||
case SONIC_RSA:
|
||||
case SONIC_REA:
|
||||
case SONIC_RRP:
|
||||
case SONIC_RWP:
|
||||
if (s->regs[SONIC_DCR] & SONIC_DCR_DW) {
|
||||
s->regs[reg] = val & 0xfffc;
|
||||
} else {
|
||||
s->regs[reg] = val & 0xfffe;
|
||||
}
|
||||
break;
|
||||
/* Invert written value for some registers */
|
||||
case SONIC_CRCT:
|
||||
case SONIC_FAET:
|
||||
case SONIC_MPT:
|
||||
s->regs[reg] = val ^ 0xffff;
|
||||
break;
|
||||
/* All other registers have no special contrainst */
|
||||
default:
|
||||
s->regs[reg] = val;
|
||||
/* Command register */
|
||||
case SONIC_CR:
|
||||
dp8393x_do_command(s, val);
|
||||
break;
|
||||
/* Prevent write to read-only registers */
|
||||
case SONIC_CAP2:
|
||||
case SONIC_CAP1:
|
||||
case SONIC_CAP0:
|
||||
case SONIC_SR:
|
||||
case SONIC_MDT:
|
||||
trace_dp8393x_write_invalid(reg);
|
||||
break;
|
||||
/* Accept write to some registers only when in reset mode */
|
||||
case SONIC_DCR:
|
||||
if (s->regs[SONIC_CR] & SONIC_CR_RST) {
|
||||
s->regs[reg] = val & 0xbfff;
|
||||
} else {
|
||||
trace_dp8393x_write_invalid_dcr("DCR");
|
||||
}
|
||||
break;
|
||||
case SONIC_DCR2:
|
||||
if (s->regs[SONIC_CR] & SONIC_CR_RST) {
|
||||
s->regs[reg] = val & 0xf017;
|
||||
} else {
|
||||
trace_dp8393x_write_invalid_dcr("DCR2");
|
||||
}
|
||||
break;
|
||||
/* 12 lower bytes are Read Only */
|
||||
case SONIC_TCR:
|
||||
s->regs[reg] = val & 0xf000;
|
||||
break;
|
||||
/* 9 lower bytes are Read Only */
|
||||
case SONIC_RCR:
|
||||
s->regs[reg] = val & 0xffe0;
|
||||
break;
|
||||
/* Ignore most significant bit */
|
||||
case SONIC_IMR:
|
||||
s->regs[reg] = val & 0x7fff;
|
||||
dp8393x_update_irq(s);
|
||||
break;
|
||||
/* Clear bits by writing 1 to them */
|
||||
case SONIC_ISR:
|
||||
val &= s->regs[reg];
|
||||
s->regs[reg] &= ~val;
|
||||
if (val & SONIC_ISR_RBE) {
|
||||
dp8393x_do_read_rra(s);
|
||||
}
|
||||
dp8393x_update_irq(s);
|
||||
break;
|
||||
/* The guest is required to store aligned pointers here */
|
||||
case SONIC_RSA:
|
||||
case SONIC_REA:
|
||||
case SONIC_RRP:
|
||||
case SONIC_RWP:
|
||||
if (s->regs[SONIC_DCR] & SONIC_DCR_DW) {
|
||||
s->regs[reg] = val & 0xfffc;
|
||||
} else {
|
||||
s->regs[reg] = val & 0xfffe;
|
||||
}
|
||||
break;
|
||||
/* Invert written value for some registers */
|
||||
case SONIC_CRCT:
|
||||
case SONIC_FAET:
|
||||
case SONIC_MPT:
|
||||
s->regs[reg] = val ^ 0xffff;
|
||||
break;
|
||||
/* All other registers have no special contrainst */
|
||||
default:
|
||||
s->regs[reg] = val;
|
||||
}
|
||||
|
||||
if (reg == SONIC_WT0 || reg == SONIC_WT1) {
|
||||
@ -747,17 +740,18 @@ static int dp8393x_receive_filter(dp8393xState *s, const uint8_t * buf,
|
||||
}
|
||||
|
||||
/* Check broadcast */
|
||||
if ((s->regs[SONIC_RCR] & SONIC_RCR_BRD) && !memcmp(buf, bcast, sizeof(bcast))) {
|
||||
if ((s->regs[SONIC_RCR] & SONIC_RCR_BRD) &&
|
||||
!memcmp(buf, bcast, sizeof(bcast))) {
|
||||
return SONIC_RCR_BC;
|
||||
}
|
||||
|
||||
/* Check CAM */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (s->regs[SONIC_CE] & (1 << i)) {
|
||||
/* Entry enabled */
|
||||
if (!memcmp(buf, s->cam[i], sizeof(s->cam[i]))) {
|
||||
return 0;
|
||||
}
|
||||
/* Entry enabled */
|
||||
if (!memcmp(buf, s->cam[i], sizeof(s->cam[i]))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -791,7 +785,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,
|
||||
}
|
||||
|
||||
if (padded_len > dp8393x_rbwc(s) * 2) {
|
||||
DPRINTF("oversize packet, pkt_size is %d\n", pkt_size);
|
||||
trace_dp8393x_receive_oversize(pkt_size);
|
||||
s->regs[SONIC_ISR] |= SONIC_ISR_RBAE;
|
||||
dp8393x_update_irq(s);
|
||||
s->regs[SONIC_RCR] |= SONIC_RCR_LPKT;
|
||||
@ -800,7 +794,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,
|
||||
|
||||
packet_type = dp8393x_receive_filter(s, buf, pkt_size);
|
||||
if (packet_type < 0) {
|
||||
DPRINTF("packet not for netcard\n");
|
||||
trace_dp8393x_receive_not_netcard();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -838,7 +832,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,
|
||||
checksum = cpu_to_le32(crc32(0, buf, pkt_size));
|
||||
|
||||
/* Put packet into RBA */
|
||||
DPRINTF("Receive packet at %08x\n", dp8393x_crba(s));
|
||||
trace_dp8393x_receive_packet(dp8393x_crba(s));
|
||||
address = dp8393x_crba(s);
|
||||
address_space_write(&s->as, address, MEMTXATTRS_UNSPECIFIED,
|
||||
buf, pkt_size);
|
||||
@ -876,7 +870,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,
|
||||
}
|
||||
|
||||
/* Write status to memory */
|
||||
DPRINTF("Write status at %08x\n", dp8393x_crda(s));
|
||||
trace_dp8393x_receive_write_status(dp8393x_crda(s));
|
||||
dp8393x_put(s, width, 0, s->regs[SONIC_RCR]); /* status */
|
||||
dp8393x_put(s, width, 1, rx_len); /* byte count */
|
||||
dp8393x_put(s, width, 2, s->regs[SONIC_TRBA0]); /* pkt_ptr0 */
|
||||
@ -938,7 +932,8 @@ static void dp8393x_reset(DeviceState *dev)
|
||||
s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux/mips */
|
||||
s->regs[SONIC_CR] = SONIC_CR_RST | SONIC_CR_STP | SONIC_CR_RXDIS;
|
||||
s->regs[SONIC_DCR] &= ~(SONIC_DCR_EXBUS | SONIC_DCR_LBR);
|
||||
s->regs[SONIC_RCR] &= ~(SONIC_RCR_LB0 | SONIC_RCR_LB1 | SONIC_RCR_BRD | SONIC_RCR_RNT);
|
||||
s->regs[SONIC_RCR] &= ~(SONIC_RCR_LB0 | SONIC_RCR_LB1 | SONIC_RCR_BRD |
|
||||
SONIC_RCR_RNT);
|
||||
s->regs[SONIC_TCR] |= SONIC_TCR_NCRS | SONIC_TCR_PTX;
|
||||
s->regs[SONIC_TCR] &= ~SONIC_TCR_BCM;
|
||||
s->regs[SONIC_IMR] = 0;
|
||||
@ -968,16 +963,12 @@ static void dp8393x_instance_init(Object *obj)
|
||||
dp8393xState *s = DP8393X(obj);
|
||||
|
||||
sysbus_init_mmio(sbd, &s->mmio);
|
||||
sysbus_init_mmio(sbd, &s->prom);
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
}
|
||||
|
||||
static void dp8393x_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
dp8393xState *s = DP8393X(dev);
|
||||
int i, checksum;
|
||||
uint8_t *prom;
|
||||
Error *local_err = NULL;
|
||||
|
||||
address_space_init(&s->as, s->dma_mr, "dp8393x");
|
||||
memory_region_init_io(&s->mmio, OBJECT(dev), &dp8393x_ops, s,
|
||||
@ -988,23 +979,6 @@ static void dp8393x_realize(DeviceState *dev, Error **errp)
|
||||
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
|
||||
|
||||
s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
|
||||
|
||||
memory_region_init_rom(&s->prom, OBJECT(dev), "dp8393x-prom",
|
||||
SONIC_PROM_SIZE, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
prom = memory_region_get_ram_ptr(&s->prom);
|
||||
checksum = 0;
|
||||
for (i = 0; i < 6; i++) {
|
||||
prom[i] = s->conf.macaddr.a[i];
|
||||
checksum += prom[i];
|
||||
if (checksum > 0xff) {
|
||||
checksum = (checksum + 1) & 0xff;
|
||||
}
|
||||
}
|
||||
prom[7] = 0xff - checksum;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_dp8393x = {
|
||||
|
@ -436,3 +436,20 @@ npcm7xx_emc_received_packet(uint32_t len) "Received %u byte packet"
|
||||
npcm7xx_emc_rx_done(uint32_t crxdsa) "RX done, CRXDSA=0x%x"
|
||||
npcm7xx_emc_reg_read(int emc_num, uint32_t result, const char *name, int regno) "emc%d: 0x%x = reg[%s/%d]"
|
||||
npcm7xx_emc_reg_write(int emc_num, const char *name, int regno, uint32_t value) "emc%d: reg[%s/%d] = 0x%x"
|
||||
|
||||
# dp8398x.c
|
||||
dp8393x_raise_irq(int isr) "raise irq, isr is 0x%04x"
|
||||
dp8393x_lower_irq(void) "lower irq"
|
||||
dp8393x_load_cam(int idx, int cam0, int cam1, int cam2, int cam3, int cam4, int cam5) "load cam[%d] with 0x%02x0x%02x0x%02x0x%02x0x%02x0x%02x"
|
||||
dp8393x_load_cam_done(int cen) "load cam done. cam enable mask 0x%04x"
|
||||
dp8393x_read_rra_regs(int crba0, int crba1, int rbwc0, int rbwc1) "CRBA0/1: 0x%04x/0x%04x, RBWC0/1: 0x%04x/0x%04x"
|
||||
dp8393x_transmit_packet(int ttda) "Transmit packet at 0x%"PRIx32
|
||||
dp8393x_transmit_txlen_error(int len) "tx_len is %d"
|
||||
dp8393x_read(int reg, const char *name, int val, int size) "reg=0x%x [%s] val=0x%04x size=%d"
|
||||
dp8393x_write(int reg, const char *name, int val, int size) "reg=0x%x [%s] val=0x%04x size=%d"
|
||||
dp8393x_write_invalid(int reg) "writing to reg %d invalid"
|
||||
dp8393x_write_invalid_dcr(const char *name) "writing to %s invalid"
|
||||
dp8393x_receive_oversize(int size) "oversize packet, pkt_size is %d"
|
||||
dp8393x_receive_not_netcard(void) "packet not for netcard"
|
||||
dp8393x_receive_packet(int crba) "Receive packet at 0x%"PRIx32
|
||||
dp8393x_receive_write_status(int crba) "Write status at 0x%"PRIx32
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "hw/misc/unimp.h"
|
||||
#include "hw/registerfields.h"
|
||||
#include "qom/object.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* #define DEBUG_BONITO */
|
||||
|
||||
@ -185,7 +186,8 @@ FIELD(BONGENCFG, PCIQUEUE, 12, 1)
|
||||
#define BONITO_PCICONF_IDSEL_OFFSET 11
|
||||
#define BONITO_PCICONF_FUN_MASK 0x700 /* [10:8] */
|
||||
#define BONITO_PCICONF_FUN_OFFSET 8
|
||||
#define BONITO_PCICONF_REG_MASK 0xFC
|
||||
#define BONITO_PCICONF_REG_MASK_DS (~3) /* Per datasheet */
|
||||
#define BONITO_PCICONF_REG_MASK_HW 0xff /* As seen running PMON */
|
||||
#define BONITO_PCICONF_REG_OFFSET 0
|
||||
|
||||
|
||||
@ -464,7 +466,7 @@ static uint32_t bonito_sbridge_pciaddr(void *opaque, hwaddr addr)
|
||||
BONITO_PCICONF_IDSEL_OFFSET;
|
||||
devno = ctz32(idsel);
|
||||
funno = (cfgaddr & BONITO_PCICONF_FUN_MASK) >> BONITO_PCICONF_FUN_OFFSET;
|
||||
regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET;
|
||||
regno = (cfgaddr & BONITO_PCICONF_REG_MASK_HW) >> BONITO_PCICONF_REG_OFFSET;
|
||||
|
||||
if (idsel == 0) {
|
||||
error_report("error in bonito pci config address 0x" TARGET_FMT_plx
|
||||
@ -495,6 +497,9 @@ static void bonito_spciconf_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
if (pciaddr == 0xffffffff) {
|
||||
return;
|
||||
}
|
||||
if (addr & ~BONITO_PCICONF_REG_MASK_DS) {
|
||||
trace_bonito_spciconf_small_access(addr, size);
|
||||
}
|
||||
|
||||
/* set the pci address in s->config_reg */
|
||||
phb->config_reg = (pciaddr) | (1u << 31);
|
||||
@ -521,6 +526,9 @@ static uint64_t bonito_spciconf_read(void *opaque, hwaddr addr, unsigned size)
|
||||
if (pciaddr == 0xffffffff) {
|
||||
return MAKE_64BIT_MASK(0, size * 8);
|
||||
}
|
||||
if (addr & ~BONITO_PCICONF_REG_MASK_DS) {
|
||||
trace_bonito_spciconf_small_access(addr, size);
|
||||
}
|
||||
|
||||
/* set the pci address in s->config_reg */
|
||||
phb->config_reg = (pciaddr) | (1u << 31);
|
||||
|
@ -1,5 +1,8 @@
|
||||
# See docs/devel/tracing.rst for syntax documentation.
|
||||
|
||||
# bonito.c
|
||||
bonito_spciconf_small_access(uint64_t addr, unsigned size) "PCI config address is smaller then 32-bit, addr: 0x%"PRIx64", size: %u"
|
||||
|
||||
# grackle.c
|
||||
grackle_set_irq(int irq_num, int level) "set_irq num %d level %d"
|
||||
|
||||
|
@ -618,4 +618,26 @@ static inline uint64_t half_unshuffle64(uint64_t x)
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* bitrev8:
|
||||
* @x: 8-bit value to be reversed
|
||||
*
|
||||
* Given an input value with bits::
|
||||
*
|
||||
* ABCDEFGH
|
||||
*
|
||||
* return the value with its bits reversed from left to right::
|
||||
*
|
||||
* HGFEDCBA
|
||||
*
|
||||
* Returns: the bit-reversed value.
|
||||
*/
|
||||
static inline uint8_t bitrev8(uint8_t x)
|
||||
{
|
||||
x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa);
|
||||
x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc);
|
||||
x = (x >> 4) | (x << 4) ;
|
||||
return x;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
3231
target/mips/tcg/micromips_translate.c.inc
Normal file
3231
target/mips/tcg/micromips_translate.c.inc
Normal file
File diff suppressed because it is too large
Load Diff
1123
target/mips/tcg/mips16e_translate.c.inc
Normal file
1123
target/mips/tcg/mips16e_translate.c.inc
Normal file
File diff suppressed because it is too large
Load Diff
4922
target/mips/tcg/nanomips_translate.c.inc
Normal file
4922
target/mips/tcg/nanomips_translate.c.inc
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -146,6 +146,11 @@ void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg);
|
||||
void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
|
||||
int get_fp_bit(int cc);
|
||||
|
||||
void gen_ldxs(DisasContext *ctx, int base, int index, int rd);
|
||||
void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp);
|
||||
void gen_addiupc(DisasContext *ctx, int rx, int imm,
|
||||
int is_64_bit, int extended);
|
||||
|
||||
/*
|
||||
* Address Computation and Large Constant Instructions
|
||||
*/
|
||||
|
42
tests/acceptance/machine_mips_fuloong2e.py
Normal file
42
tests/acceptance/machine_mips_fuloong2e.py
Normal file
@ -0,0 +1,42 @@
|
||||
# Functional tests for the Lemote Fuloong-2E machine.
|
||||
#
|
||||
# Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
#
|
||||
# This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
# See the COPYING file in the top-level directory.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
|
||||
from avocado import skipUnless
|
||||
from avocado_qemu import Test
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
|
||||
class MipsFuloong2e(Test):
|
||||
|
||||
timeout = 60
|
||||
|
||||
@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
@skipUnless(os.getenv('RESCUE_YL_PATH'), 'RESCUE_YL_PATH not available')
|
||||
def test_linux_kernel_isa_serial(self):
|
||||
"""
|
||||
:avocado: tags=arch:mips64el
|
||||
:avocado: tags=machine:fuloong2e
|
||||
:avocado: tags=endian:little
|
||||
:avocado: tags=device:bonito64
|
||||
:avocado: tags=device:via686b
|
||||
"""
|
||||
# Recovery system for the Yeeloong laptop
|
||||
# (enough to test the fuloong2e southbridge, accessing its ISA bus)
|
||||
# http://dev.lemote.com/files/resource/download/rescue/rescue-yl
|
||||
kernel_hash = 'ec4d1bd89a8439c41033ca63db60160cc6d6f09a'
|
||||
kernel_path = self.fetch_asset('file://' + os.getenv('RESCUE_YL_PATH'),
|
||||
asset_hash=kernel_hash)
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', kernel_path)
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'Linux version 2.6.27.7lemote')
|
||||
cpu_revision = 'CPU revision is: 00006302 (ICT Loongson-2)'
|
||||
wait_for_console_pattern(self, cpu_revision)
|
Loading…
Reference in New Issue
Block a user