[OpenBIOS] Trying to figure out what 9 means to the escc

Hervé Poussineau hpoussin at reactos.org
Thu Feb 25 09:39:23 CET 2016


Le 24/02/2016 21:13, Programmingkid a écrit :
> With the below patch I can see that Mac OS 9.0 is having escc_mem_write() go to the SERIAL_CTRL case. Then to the W_CMD case. Then to the CMD_HI case. This then causes newreg to be set to the value 9. What I need to know is what is this value for. Does anyone know what it means?

Basically, you need to first select to which register you write, and then, which value you want to write to this selected register.

Here, you write to register 0 W_CMD to choose the register 9 (by register mask value 1 + Point High Command, which adds 8) [pdf page 148], which is "Master Interrupt Control" register (W_MINTR)
Then, you write 0xc0 to the previously selected register W_MINTR; c0 is reset for channels A & B [pdf page 167]

Hervé

>
> Afterwords Mac OS 9.0 will write the value 0xc0 to the escc. This causes the escc to reset.
>
> This pdf might be helpful for anyone who is interested in helping: http://www.zilog.com/docs/serial/scc_escc_um.pdf
>
> ---
>   hw/char/escc.c |   28 ++++++++++++++++++++++++++++
>   1 files changed, 28 insertions(+), 0 deletions(-)
>
> diff --git a/hw/char/escc.c b/hw/char/escc.c
> index 98a1c21..f1fc70e 100644
> --- a/hw/char/escc.c
> +++ b/hw/char/escc.c
> @@ -472,6 +472,7 @@ static void escc_update_parameters(ChannelState *s)
>   static void escc_mem_write(void *opaque, hwaddr addr,
>                              uint64_t val, unsigned size)
>   {
> +
>       ESCCState *serial = opaque;
>       ChannelState *s;
>       uint32_t saddr;
> @@ -481,22 +482,31 @@ static void escc_mem_write(void *opaque, hwaddr addr,
>       saddr = (addr >> serial->it_shift) & 1;
>       channel = (addr >> (serial->it_shift + 1)) & 1;
>       s = &serial->chn[channel];
> +
> +    printf("%s(): start value:0x%x register:0x%x\n", __func__, val, saddr);
> +
>       switch (saddr) {
>       case SERIAL_CTRL:
> +        printf("%s() SERIAL_CTRL case\n", __func__);
>           trace_escc_mem_writeb_ctrl(CHN_C(s), s->reg, val & 0xff);
>           newreg = 0;
>           switch (s->reg) {
>           case W_CMD:
> +            printf("%s() W_CMD case\n", __func__);
>               newreg = val & CMD_PTR_MASK;
>               val &= CMD_CMD_MASK;
>               switch (val) {
>               case CMD_HI:
> +                printf("%s() CMD_HI case\n", __func__);
>                   newreg |= CMD_HI;
> +                printf("%s(): newreg = 0x%x\n", __func__, newreg);
>                   break;
>               case CMD_CLR_TXINT:
> +                printf("%s() CMD_CLR_TXINT case\n", __func__);
>                   clr_txint(s);
>                   break;
>               case CMD_CLR_IUS:
> +                printf("%s() CMD_CLR_IUS case\n", __func__);
>                   if (s->rxint_under_svc) {
>                       s->rxint_under_svc = 0;
>                       if (s->txint) {
> @@ -508,6 +518,7 @@ static void escc_mem_write(void *opaque, hwaddr addr,
>                   escc_update_irq(s);
>                   break;
>               default:
> +                printf("%s(): unprogrammed command detected: value:%d\n", __func__, val);
>                   break;
>               }
>               break;
> @@ -515,36 +526,44 @@ static void escc_mem_write(void *opaque, hwaddr addr,
>           case W_SYNC1 ... W_TXBUF:
>           case W_MISC1 ... W_CLOCK:
>           case W_MISC2 ... W_EXTINT:
> +            printf("%s() W_MISC2 case\n", __func__);
>               s->wregs[s->reg] = val;
>               break;
>           case W_TXCTRL1:
>           case W_TXCTRL2:
> +            printf("%s() W_TXCTRL2 case\n", __func__);
>               s->wregs[s->reg] = val;
>               escc_update_parameters(s);
>               break;
>           case W_BRGLO:
>           case W_BRGHI:
> +            printf("%s() W_BRGHI case\n", __func__);
>               s->wregs[s->reg] = val;
>               s->rregs[s->reg] = val;
>               escc_update_parameters(s);
>               break;
>           case W_MINTR:
> +            printf("%s(): W_MINTR detected\n", __func__);
>               switch (val & MINTR_RST_MASK) {
>               case 0:
>               default:
>                   break;
>               case MINTR_RST_B:
> +                printf("%s() MINTR_RST_B case\n", __func__);
>                   escc_reset_chn(&serial->chn[0]);
>                   return;
>               case MINTR_RST_A:
> +                printf("%s() MINTR_RST_A case\n", __func__);
>                   escc_reset_chn(&serial->chn[1]);
>                   return;
>               case MINTR_RST_ALL:
> +                printf("%s(): MINTR_RST_ALL case\n", __func__);
>                   escc_reset(DEVICE(serial));
>                   return;
>               }
>               break;
>           default:
> +            printf("%s(): unprogrammed command detected: value:%d\n", __func__, val);
>               break;
>           }
>           if (s->reg == 0)
> @@ -553,6 +572,7 @@ static void escc_mem_write(void *opaque, hwaddr addr,
>               s->reg = 0;
>           break;
>       case SERIAL_DATA:
> +        printf("%s() SERIAL_DATA case\n", __func__);
>           trace_escc_mem_writeb_data(CHN_C(s), val);
>           s->tx = val;
>           if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
> @@ -567,6 +587,7 @@ static void escc_mem_write(void *opaque, hwaddr addr,
>           set_txint(s);
>           break;
>       default:
> +        printf("%s(): unprogrammed command detected: value:%d\n", __func__, val);
>           break;
>       }
>   }
> @@ -583,11 +604,16 @@ static uint64_t escc_mem_read(void *opaque, hwaddr addr,
>       saddr = (addr >> serial->it_shift) & 1;
>       channel = (addr >> (serial->it_shift + 1)) & 1;
>       s = &serial->chn[channel];
> +
> +    printf("%s(): address:0x%x saddr:0x%x\n", __func__, addr, saddr);
> +
>       switch (saddr) {
>       case SERIAL_CTRL:
>           trace_escc_mem_readb_ctrl(CHN_C(s), s->reg, s->rregs[s->reg]);
> +        printf("%s(): s->reg = 0x%x\n", __func__, s->reg);
>           ret = s->rregs[s->reg];
>           s->reg = 0;
> +        printf("%s(): SERIAL_CTRL returning 0x%x\n", __func__, ret);
>           return ret;
>       case SERIAL_DATA:
>           s->rregs[R_STATUS] &= ~STATUS_RXAV;
> @@ -599,8 +625,10 @@ static uint64_t escc_mem_read(void *opaque, hwaddr addr,
>           trace_escc_mem_readb_data(CHN_C(s), ret);
>           if (s->chr)
>               qemu_chr_accept_input(s->chr);
> +        printf("%s(): SERIAL_DATA returning 0x%x\n", __func__, ret);
>           return ret;
>       default:
> +        printf("%s(): default case for address 0x%x\n", __func__, addr);
>           break;
>       }
>       return 0;
>




More information about the OpenBIOS mailing list