📄 mips_malta.c
字号:
/* * QEMU Malta board support * * Copyright (c) 2006 Aurelien Jarno * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */#include "vl.h"#ifdef TARGET_WORDS_BIGENDIAN#define BIOS_FILENAME "mips_bios.bin"#else#define BIOS_FILENAME "mipsel_bios.bin"#endif#ifdef MIPS_HAS_MIPS64#define INITRD_LOAD_ADDR (int64_t)0x80800000#else#define INITRD_LOAD_ADDR (int32_t)0x80800000#endif#define ENVP_ADDR (int32_t)0x80002000#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))#define ENVP_NB_ENTRIES 16#define ENVP_ENTRY_SIZE 256extern FILE *logfile;typedef struct { uint32_t leds; uint32_t brk; uint32_t gpout; uint32_t i2coe; uint32_t i2cout; uint32_t i2csel; CharDriverState *display; char display_text[9];} MaltaFPGAState;static PITState *pit;/* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */static void pic_irq_request(void *opaque, int level){ cpu_mips_irq_request(opaque, 2, level);}/* Malta FPGA */static void malta_fpga_update_display(void *opaque){ char leds_text[9]; int i; MaltaFPGAState *s = opaque; for (i = 7 ; i >= 0 ; i--) { if (s->leds & (1 << i)) leds_text[i] = '#'; else leds_text[i] = ' '; } leds_text[8] = '\0'; qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text); qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);}static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr){ MaltaFPGAState *s = opaque; uint32_t val = 0; uint32_t saddr; saddr = (addr & 0xfffff); switch (saddr) { /* SWITCH Register */ case 0x00200: val = 0x00000000; /* All switches closed */ break; /* STATUS Register */ case 0x00208:#ifdef TARGET_WORDS_BIGENDIAN val = 0x00000012;#else val = 0x00000010;#endif break; /* JMPRS Register */ case 0x00210: val = 0x00; break; /* LEDBAR Register */ case 0x00408: val = s->leds; break; /* BRKRES Register */ case 0x00508: val = s->brk; break; /* GPOUT Register */ case 0x00a00: val = s->gpout; break; /* XXX: implement a real I2C controller */ /* GPINP Register */ case 0x00a08: /* IN = OUT until a real I2C control is implemented */ if (s->i2csel) val = s->i2cout; else val = 0x00; break; /* I2CINP Register */ case 0x00b00: val = 0x00000003; break; /* I2COE Register */ case 0x00b08: val = s->i2coe; break; /* I2COUT Register */ case 0x00b10: val = s->i2cout; break; /* I2CSEL Register */ case 0x00b18: val = s->i2cout; break; default:#if 0 printf ("malta_fpga_read: Bad register offset 0x" TLSZ "\n", addr);#endif break; } return val;}static void malta_fpga_writel(void *opaque, target_phys_addr_t addr, uint32_t val){ MaltaFPGAState *s = opaque; uint32_t saddr; saddr = (addr & 0xfffff); switch (saddr) { /* SWITCH Register */ case 0x00200: break; /* JMPRS Register */ case 0x00210: break; /* LEDBAR Register */ /* XXX: implement a 8-LED array */ case 0x00408: s->leds = val & 0xff; break; /* ASCIIWORD Register */ case 0x00410: snprintf(s->display_text, 9, "%08X", val); malta_fpga_update_display(s); break; /* ASCIIPOS0 to ASCIIPOS7 Registers */ case 0x00418: case 0x00420: case 0x00428: case 0x00430: case 0x00438: case 0x00440: case 0x00448: case 0x00450: s->display_text[(saddr - 0x00418) >> 3] = (char) val; malta_fpga_update_display(s); break; /* SOFTRES Register */ case 0x00500: if (val == 0x42) qemu_system_reset_request (); break; /* BRKRES Register */ case 0x00508: s->brk = val & 0xff; break; /* GPOUT Register */ case 0x00a00: s->gpout = val & 0xff; break; /* I2COE Register */ case 0x00b08: s->i2coe = val & 0x03; break; /* I2COUT Register */ case 0x00b10: s->i2cout = val & 0x03; break; /* I2CSEL Register */ case 0x00b18: s->i2cout = val & 0x01; break; default:#if 0 printf ("malta_fpga_write: Bad register offset 0x" TLSZ "\n", addr);#endif break; }}static CPUReadMemoryFunc *malta_fpga_read[] = { malta_fpga_readl, malta_fpga_readl, malta_fpga_readl};static CPUWriteMemoryFunc *malta_fpga_write[] = { malta_fpga_writel, malta_fpga_writel, malta_fpga_writel};void malta_fpga_reset(void *opaque){ MaltaFPGAState *s = opaque; s->leds = 0x00; s->brk = 0x0a; s->gpout = 0x00; s->i2coe = 0x0; s->i2cout = 0x3; s->i2csel = 0x1; s->display_text[8] = '\0'; snprintf(s->display_text, 9, " "); malta_fpga_update_display(s);}MaltaFPGAState *malta_fpga_init(target_phys_addr_t base){ MaltaFPGAState *s; int malta; s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState)); malta = cpu_register_io_memory(0, malta_fpga_read, malta_fpga_write, s); cpu_register_physical_memory(base, 0x100000, malta); s->display = qemu_chr_open("vc"); qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n"); qemu_chr_printf(s->display, "+--------+\r\n"); qemu_chr_printf(s->display, "+ +\r\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -