cmos return current date - current irq priority in PIC (L4 Pistachio support) - help fixes

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@557 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2004-01-18 21:56:49 +00:00
parent 6986f88c3f
commit 6e44ba7fa2
1 changed files with 138 additions and 81 deletions

219
vl.c
View File

@ -525,44 +525,15 @@ void cmos_ioport_write(CPUState *env, uint32_t addr, uint32_t data)
}
}
uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
{
int ret;
if (addr == 0x70) {
return 0xff;
} else {
ret = cmos_data[cmos_index];
switch(cmos_index) {
case RTC_REG_A:
/* toggle update-in-progress bit for Linux (same hack as
plex86) */
cmos_data[RTC_REG_A] ^= 0x80;
break;
case RTC_REG_C:
pic_set_irq(8, 0);
cmos_data[RTC_REG_C] = 0x00;
break;
}
#ifdef DEBUG_CMOS
printf("cmos: read index=0x%02x val=0x%02x\n",
cmos_index, ret);
#endif
return ret;
}
}
static inline int to_bcd(int a)
{
return ((a / 10) << 4) | (a % 10);
}
void cmos_init(void)
static void cmos_update_time(void)
{
struct tm *tm;
time_t ti;
int val;
ti = time(NULL);
tm = gmtime(&ti);
@ -573,6 +544,56 @@ void cmos_init(void)
cmos_data[RTC_DAY_OF_MONTH] = to_bcd(tm->tm_mday);
cmos_data[RTC_MONTH] = to_bcd(tm->tm_mon + 1);
cmos_data[RTC_YEAR] = to_bcd(tm->tm_year % 100);
cmos_data[REG_IBM_CENTURY_BYTE] = to_bcd((tm->tm_year / 100) + 19);
}
uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
{
int ret;
if (addr == 0x70) {
return 0xff;
} else {
switch(cmos_index) {
case RTC_SECONDS:
case RTC_MINUTES:
case RTC_HOURS:
case RTC_DAY_OF_WEEK:
case RTC_DAY_OF_MONTH:
case RTC_MONTH:
case RTC_YEAR:
case REG_IBM_CENTURY_BYTE:
cmos_update_time();
ret = cmos_data[cmos_index];
break;
case RTC_REG_A:
ret = cmos_data[cmos_index];
/* toggle update-in-progress bit for Linux (same hack as
plex86) */
cmos_data[RTC_REG_A] ^= 0x80;
break;
case RTC_REG_C:
ret = cmos_data[cmos_index];
pic_set_irq(8, 0);
cmos_data[RTC_REG_C] = 0x00;
break;
default:
ret = cmos_data[cmos_index];
break;
}
#ifdef DEBUG_CMOS
printf("cmos: read index=0x%02x val=0x%02x\n",
cmos_index, ret);
#endif
return ret;
}
}
void cmos_init(void)
{
int val;
cmos_update_time();
cmos_data[RTC_REG_A] = 0x26;
cmos_data[RTC_REG_B] = 0x02;
@ -580,7 +601,6 @@ void cmos_init(void)
cmos_data[RTC_REG_D] = 0x80;
/* various important CMOS locations needed by PC/Bochs bios */
cmos_data[REG_IBM_CENTURY_BYTE] = to_bcd((tm->tm_year / 100) + 19);
cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */
cmos_data[REG_EQUIPMENT_BYTE] |= 0x04; /* PS/2 mouse installed */
@ -676,14 +696,15 @@ typedef struct PicState {
uint8_t irr; /* interrupt request register */
uint8_t imr; /* interrupt mask register */
uint8_t isr; /* interrupt service register */
uint8_t priority_add; /* used to compute irq priority */
uint8_t priority_add; /* highest irq priority */
uint8_t irq_base;
uint8_t read_reg_select;
uint8_t poll;
uint8_t special_mask;
uint8_t init_state;
uint8_t auto_eoi;
uint8_t rotate_on_autoeoi;
uint8_t rotate_on_auto_eoi;
uint8_t special_fully_nested_mode;
uint8_t init4; /* true if 4 byte init */
} PicState;
@ -705,14 +726,16 @@ static inline void pic_set_irq1(PicState *s, int irq, int level)
}
}
/* return the highest priority found in mask (highest = smallest
number). Return 8 if no irq */
static inline int get_priority(PicState *s, int mask)
{
int priority;
if (mask == 0)
return -1;
priority = 7;
return 8;
priority = 0;
while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
priority--;
priority++;
return priority;
}
@ -723,13 +746,18 @@ static int pic_get_irq(PicState *s)
mask = s->irr & ~s->imr;
priority = get_priority(s, mask);
if (priority < 0)
if (priority == 8)
return -1;
/* compute current priority */
cur_priority = get_priority(s, s->isr);
if (priority > cur_priority) {
/* compute current priority. If special fully nested mode on the
master, the IRQ coming from the slave is not taken into account
for the priority computation. */
mask = s->isr;
if (s->special_fully_nested_mode && s == &pics[0])
mask &= ~(1 << 2);
cur_priority = get_priority(s, mask);
if (priority < cur_priority) {
/* higher priority found: an irq should be generated */
return priority;
return (priority + s->priority_add) & 7;
} else {
return -1;
}
@ -758,6 +786,17 @@ void pic_update_irq(void)
/* from master pic */
pic_irq_requested = irq;
}
#if defined(DEBUG_PIC)
{
int i;
for(i = 0; i < 2; i++) {
printf("pic%d: imr=%x irr=%x padd=%d\n",
i, pics[i].imr, pics[i].irr, pics[i].priority_add);
}
}
printf("pic: cpu_interrupt req=%d\n", pic_irq_requested);
#endif
cpu_interrupt(global_env, CPU_INTERRUPT_HARD);
}
}
@ -787,6 +826,18 @@ void pic_set_irq(int irq, int level)
pic_update_irq();
}
/* acknowledge interrupt 'irq' */
static inline void pic_intack(PicState *s, int irq)
{
if (s->auto_eoi) {
if (s->rotate_on_auto_eoi)
s->priority_add = (irq + 1) & 7;
} else {
s->isr |= (1 << irq);
}
s->irr &= ~(1 << irq);
}
int cpu_x86_get_pic_interrupt(CPUState *env)
{
int irq, irq2, intno;
@ -804,22 +855,20 @@ int cpu_x86_get_pic_interrupt(CPUState *env)
if (irq >= 8) {
irq2 = irq & 7;
pics[1].isr |= (1 << irq2);
pics[1].irr &= ~(1 << irq2);
pic_intack(&pics[1], irq2);
irq = 2;
intno = pics[1].irq_base + irq2;
} else {
intno = pics[0].irq_base + irq;
}
pics[0].isr |= (1 << irq);
pics[0].irr &= ~(1 << irq);
pic_intack(&pics[0], irq);
return intno;
}
void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
{
PicState *s;
int priority;
int priority, cmd, irq;
#ifdef DEBUG_PIC
printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val);
@ -837,45 +886,48 @@ void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
if (val & 0x08)
hw_error("level sensitive irq not supported");
} else if (val & 0x08) {
if (val & 0x04) {
if (val & 0x04)
s->poll = 1;
} else {
if (val & 0x02)
s->read_reg_select = val & 1;
if (val & 0x40)
s->special_mask = (val >> 5) & 1;
}
} else {
switch(val) {
case 0x00:
case 0x80:
s->rotate_on_autoeoi = val >> 7;
cmd = val >> 5;
switch(cmd) {
case 0:
case 4:
s->rotate_on_auto_eoi = cmd >> 2;
break;
case 0x20: /* end of interrupt */
case 0xa0:
case 1: /* end of interrupt */
case 5:
priority = get_priority(s, s->isr);
if (priority >= 0) {
s->isr &= ~(1 << ((priority + s->priority_add) & 7));
if (priority != 8) {
irq = (priority + s->priority_add) & 7;
s->isr &= ~(1 << irq);
if (cmd == 5)
s->priority_add = (irq + 1) & 7;
pic_update_irq();
}
if (val == 0xa0)
s->priority_add = (s->priority_add + 1) & 7;
break;
case 3:
irq = val & 7;
s->isr &= ~(1 << irq);
pic_update_irq();
break;
case 0x60 ... 0x67:
priority = val & 7;
s->isr &= ~(1 << priority);
pic_update_irq();
break;
case 0xc0 ... 0xc7:
case 6:
s->priority_add = (val + 1) & 7;
pic_update_irq();
break;
case 0xe0 ... 0xe7:
priority = val & 7;
s->isr &= ~(1 << priority);
s->priority_add = (priority + 1) & 7;
case 7:
irq = val & 7;
s->isr &= ~(1 << irq);
s->priority_add = (irq + 1) & 7;
pic_update_irq();
break;
default:
/* no operation */
break;
}
}
} else {
@ -897,6 +949,7 @@ void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
}
break;
case 3:
s->special_fully_nested_mode = (val >> 4) & 1;
s->auto_eoi = (val >> 1) & 1;
s->init_state = 0;
break;
@ -935,18 +988,18 @@ uint32_t pic_ioport_read(CPUState *env, uint32_t addr1)
addr = addr1;
s = &pics[addr >> 7];
addr &= 1;
if (s->poll == 1) {
if (s->poll) {
ret = pic_poll_read(s, addr1);
s->poll = 0;
} else {
if (addr == 0) {
if (s->read_reg_select)
ret = s->isr;
else
ret = s->irr;
} else {
ret = s->imr;
}
if (addr == 0) {
if (s->read_reg_select)
ret = s->isr;
else
ret = s->irr;
} else {
ret = s->imr;
}
}
#ifdef DEBUG_PIC
printf("pic_read: addr=0x%02x val=0x%02x\n", addr1, ret);
@ -1729,6 +1782,9 @@ void serial_received_byte(SerialState *s, int ch)
fflush(stdout);
term_command = 1;
break;
case 'd':
cpu_set_log(CPU_LOG_ALL);
break;
case TERM_ESCAPE:
goto send_char;
}
@ -3180,7 +3236,7 @@ void help(void)
"-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
"-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
"-cdrom file use 'file' as IDE cdrom 2 image\n"
"-boot [c|d] boot on hard disk (c) or CD-ROM (d)\n"
"-boot [a|b|c|d] boot on floppy (a, b), hard disk (c) or CD-ROM (d)\n"
"-snapshot write to temporary files instead of disk image files\n"
"-m megs set virtual RAM size to megs MB\n"
"-n script set network init script [default=%s]\n"
@ -3195,7 +3251,7 @@ void help(void)
"Debug/Expert options:\n"
"-s wait gdb connection to port %d\n"
"-p port change gdb connection port\n"
"-d output log in /tmp/vl.log\n"
"-d output log to %s\n"
"-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n"
"-L path set the directory for the BIOS and VGA BIOS\n"
"\n"
@ -3206,7 +3262,8 @@ void help(void)
"qemu-fast",
#endif
DEFAULT_NETWORK_SCRIPT,
DEFAULT_GDBSTUB_PORT);
DEFAULT_GDBSTUB_PORT,
"/tmp/qemu.log");
term_print_help();
#ifndef CONFIG_SOFTMMU
printf("\n"