diff --git a/librz/arch/isa/pic/pic16f_memmaps/memmaps.h b/librz/arch/isa/pic/pic16f_memmaps/memmaps.h new file mode 100644 index 00000000000..ed1aaeaca2c --- /dev/null +++ b/librz/arch/isa/pic/pic16f_memmaps/memmaps.h @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2023 Siddharth Mishra +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef PIC16F_MEMMAPS_H_ +#define PIC16F_MEMMAPS_H_ + +#include "pic16f882.h" +#include "pic16f883_4.h" +#include "pic16f886_7.h" + +#endif // PIC16F_MEMMAPS_H_ diff --git a/librz/arch/isa/pic/pic16f_memmaps/pic16f882.h b/librz/arch/isa/pic/pic16f_memmaps/pic16f882.h new file mode 100644 index 00000000000..a9a56a1c534 --- /dev/null +++ b/librz/arch/isa/pic/pic16f_memmaps/pic16f882.h @@ -0,0 +1,540 @@ +// SPDX-FileCopyrightText: 2023 Siddharth Mishra +// SPDX-License-Identifier: LGPL-3.0-only + +/** + * This file describes the memory map of PICF16882 device in PIC16F family. + * */ + +#ifndef RZ_PIC_MIDRANGE_PIC_MEMMAP_PIC16F882_H +#define RZ_PIC_MIDRANGE_PIC_MEMMAP_PIC16F882_H + +#include "regtypes.h" + +// clang-format off +PicMidrangeRegType pic16f882_reg_map[] = { + /* BANK 0 */ + INDF, /* 0x00 */ + TMR0, /* 0x01 */ + PCL, /* 0x02 */ + STATUS, /* 0x03 */ + FSR, /* 0x04 */ + PORTA, /* 0x05 */ + PORTB, /* 0x06 */ + PORTC, /* 0x07 */ + UNIMPLEMENTED, /* 0x08 */ + PORTE, /* 0x09 */ + PCLATH, /* 0x0a */ + INTCON, /* 0x0b */ + PIR1, /* 0x0c */ + PIR2, /* 0x0d */ + TMR1L, /* 0x0e */ + TMR1H, /* 0x0f */ + T1CON, /* 0x10 */ + TMR2, /* 0x11 */ + T2CON, /* 0x12 */ + SSPBUF, /* 0x13 */ + SSPCON, /* 0x14 */ + CCPR1L, /* 0x15 */ + CCPR1H, /* 0x16 */ + CCP1CON, /* 0x17 */ + RCSTA, /* 0x18 */ + TXREG, /* 0x19 */ + RCREG, /* 0x1a */ + CCPR2L, /* 0x1b */ + CCPR2H, /* 0x1c */ + CCP2CON, /* 0x1d */ + ADRESH, /* 0x1e */ + ADCON0, /* 0x1f */ + FREG, /* 0x20 */ + FREG, /* 0x21 */ + FREG, /* 0x22 */ + FREG, /* 0x23 */ + FREG, /* 0x24 */ + FREG, /* 0x25 */ + FREG, /* 0x26 */ + FREG, /* 0x27 */ + FREG, /* 0x28 */ + FREG, /* 0x29 */ + FREG, /* 0x2a */ + FREG, /* 0x2b */ + FREG, /* 0x2c */ + FREG, /* 0x2d */ + FREG, /* 0x2e */ + FREG, /* 0x2f */ + FREG, /* 0x30 */ + FREG, /* 0x31 */ + FREG, /* 0x32 */ + FREG, /* 0x33 */ + FREG, /* 0x34 */ + FREG, /* 0x35 */ + FREG, /* 0x36 */ + FREG, /* 0x37 */ + FREG, /* 0x38 */ + FREG, /* 0x39 */ + FREG, /* 0x3a */ + FREG, /* 0x3b */ + FREG, /* 0x3c */ + FREG, /* 0x3d */ + FREG, /* 0x3e */ + FREG, /* 0x3f */ + FREG, /* 0x40 */ + FREG, /* 0x41 */ + FREG, /* 0x42 */ + FREG, /* 0x43 */ + FREG, /* 0x44 */ + FREG, /* 0x45 */ + FREG, /* 0x46 */ + FREG, /* 0x47 */ + FREG, /* 0x48 */ + FREG, /* 0x49 */ + FREG, /* 0x4a */ + FREG, /* 0x4b */ + FREG, /* 0x4c */ + FREG, /* 0x4d */ + FREG, /* 0x4e */ + FREG, /* 0x4f */ + FREG, /* 0x50 */ + FREG, /* 0x51 */ + FREG, /* 0x52 */ + FREG, /* 0x53 */ + FREG, /* 0x54 */ + FREG, /* 0x55 */ + FREG, /* 0x56 */ + FREG, /* 0x57 */ + FREG, /* 0x58 */ + FREG, /* 0x59 */ + FREG, /* 0x5a */ + FREG, /* 0x5b */ + FREG, /* 0x5c */ + FREG, /* 0x5d */ + FREG, /* 0x5e */ + FREG, /* 0x5f */ + FREG, /* 0x60 */ + FREG, /* 0x61 */ + FREG, /* 0x62 */ + FREG, /* 0x63 */ + FREG, /* 0x64 */ + FREG, /* 0x65 */ + FREG, /* 0x66 */ + FREG, /* 0x67 */ + FREG, /* 0x68 */ + FREG, /* 0x69 */ + FREG, /* 0x6a */ + FREG, /* 0x6b */ + FREG, /* 0x6c */ + FREG, /* 0x6d */ + FREG, /* 0x6e */ + FREG, /* 0x6f */ + FREG, /* 0x70 */ + FREG, /* 0x71 */ + FREG, /* 0x72 */ + FREG, /* 0x73 */ + FREG, /* 0x74 */ + FREG, /* 0x75 */ + FREG, /* 0x76 */ + FREG, /* 0x77 */ + FREG, /* 0x78 */ + FREG, /* 0x79 */ + FREG, /* 0x7a */ + FREG, /* 0x7b */ + FREG, /* 0x7c */ + FREG, /* 0x7d */ + FREG, /* 0x7e */ + FREG, /* 0x7f */ + + /* BANK1 */ + + INDF, /* 0x80 */ + OPTION_REG, /* 0x81 */ + PCL, /* 0x82 */ + STATUS, /* 0x83 */ + FSR, /* 0x84 */ + TRISA, /* 0x85 */ + TRISB, /* 0x86 */ + TRISC, /* 0x87 */ + UNIMPLEMENTED, /* 0x88 */ + TRISE, /* 0x89 */ + PCLATH, /* 0x8a */ + INTCON, /* 0x8b */ + PIE1, /* 0x8c */ + PIE2, /* 0x8d */ + PCON, /* 0x8e */ + OSCCON, /* 0x8f */ + OSCTUNE, /* 0x90 */ + SSPCON2, /* 0x91 */ + PR2, /* 0x92 */ + SSPADD, /* 0x93 */ + SSPSTAT, /* 0x94 */ + WPUB, /* 0x95 */ + IOCB, /* 0x96 */ + VRCON, /* 0x97 */ + RCSTA, /* 0x98 */ + TXSTA, /* 0x99 */ + SPBRG, /* 0x9a */ + SPBRGH, /* 0x9b */ + PWM1CON, /* 0x9c */ + ECCPAS, /* 0x9d */ + ADRESL, /* 0x9e */ + ADCON1, /* 0x9f */ + FREG, /* 0xa0 */ + FREG, /* 0xa1 */ + FREG, /* 0xa2 */ + FREG, /* 0xa3 */ + FREG, /* 0xa4 */ + FREG, /* 0xa5 */ + FREG, /* 0xa6 */ + FREG, /* 0xa7 */ + FREG, /* 0xa8 */ + FREG, /* 0xa9 */ + FREG, /* 0xaa */ + FREG, /* 0xab */ + FREG, /* 0xac */ + FREG, /* 0xad */ + FREG, /* 0xae */ + FREG, /* 0xaf */ + FREG, /* 0xb0 */ + FREG, /* 0xb1 */ + FREG, /* 0xb2 */ + FREG, /* 0xb3 */ + FREG, /* 0xb4 */ + FREG, /* 0xb5 */ + FREG, /* 0xb6 */ + FREG, /* 0xb7 */ + FREG, /* 0xb8 */ + FREG, /* 0xb9 */ + FREG, /* 0xba */ + FREG, /* 0xbb */ + FREG, /* 0xbc */ + FREG, /* 0xbd */ + FREG, /* 0xbe */ + FREG, /* 0xbf */ + UNIMPLEMENTED, /* 0xc0 */ + UNIMPLEMENTED, /* 0xc1 */ + UNIMPLEMENTED, /* 0xc2 */ + UNIMPLEMENTED, /* 0xc3 */ + UNIMPLEMENTED, /* 0xc4 */ + UNIMPLEMENTED, /* 0xc5 */ + UNIMPLEMENTED, /* 0xc6 */ + UNIMPLEMENTED, /* 0xc7 */ + UNIMPLEMENTED, /* 0xc8 */ + UNIMPLEMENTED, /* 0xc9 */ + UNIMPLEMENTED, /* 0xca */ + UNIMPLEMENTED, /* 0xcb */ + UNIMPLEMENTED, /* 0xcc */ + UNIMPLEMENTED, /* 0xcd */ + UNIMPLEMENTED, /* 0xce */ + UNIMPLEMENTED, /* 0xcf */ + UNIMPLEMENTED, /* 0xd0 */ + UNIMPLEMENTED, /* 0xd1 */ + UNIMPLEMENTED, /* 0xd2 */ + UNIMPLEMENTED, /* 0xd3 */ + UNIMPLEMENTED, /* 0xd4 */ + UNIMPLEMENTED, /* 0xd5 */ + UNIMPLEMENTED, /* 0xd6 */ + UNIMPLEMENTED, /* 0xd7 */ + UNIMPLEMENTED, /* 0xd8 */ + UNIMPLEMENTED, /* 0xd9 */ + UNIMPLEMENTED, /* 0xda */ + UNIMPLEMENTED, /* 0xdb */ + UNIMPLEMENTED, /* 0xdc */ + UNIMPLEMENTED, /* 0xdd */ + UNIMPLEMENTED, /* 0xde */ + UNIMPLEMENTED, /* 0xdf */ + UNIMPLEMENTED, /* 0xe0 */ + UNIMPLEMENTED, /* 0xe1 */ + UNIMPLEMENTED, /* 0xe2 */ + UNIMPLEMENTED, /* 0xe3 */ + UNIMPLEMENTED, /* 0xe4 */ + UNIMPLEMENTED, /* 0xe5 */ + UNIMPLEMENTED, /* 0xe6 */ + UNIMPLEMENTED, /* 0xe7 */ + UNIMPLEMENTED, /* 0xe8 */ + UNIMPLEMENTED, /* 0xe9 */ + UNIMPLEMENTED, /* 0xea */ + UNIMPLEMENTED, /* 0xeb */ + UNIMPLEMENTED, /* 0xec */ + UNIMPLEMENTED, /* 0xed */ + UNIMPLEMENTED, /* 0xee */ + UNIMPLEMENTED, /* 0xef */ + FREG, /* 0xf0 */ + FREG, /* 0xf1 */ + FREG, /* 0xf2 */ + FREG, /* 0xf3 */ + FREG, /* 0xf4 */ + FREG, /* 0xf5 */ + FREG, /* 0xf6 */ + FREG, /* 0xf7 */ + FREG, /* 0xf8 */ + FREG, /* 0xf9 */ + FREG, /* 0xfa */ + FREG, /* 0xfb */ + FREG, /* 0xfc */ + FREG, /* 0xfd */ + FREG, /* 0xfe */ + FREG, /* 0xff */ + + /* BANK 2 */ + + INDF, /* 0x100 */ + TMR0, /* 0x101 */ + PCL, /* 0x102 */ + STATUS, /* 0x103 */ + FSR, /* 0x104 */ + WDTCON, /* 0x105 */ + PORTB, /* 0x106 */ + CM1CON0, /* 0x107 */ + CM2CON0, /* 0x108 */ + CM2CON1, /* 0x109 */ + PCLATH, /* 0x10a */ + INTCON, /* 0x10b */ + EEDAT, /* 0x10c */ + EEADR, /* 0x10d */ + EEDATH, /* 0x10e */ + EEADRH, /* 0x10f */ + UNIMPLEMENTED, /* 0x110 */ + UNIMPLEMENTED, /* 0x111 */ + UNIMPLEMENTED, /* 0x112 */ + UNIMPLEMENTED, /* 0x113 */ + UNIMPLEMENTED, /* 0x114 */ + UNIMPLEMENTED, /* 0x115 */ + UNIMPLEMENTED, /* 0x116 */ + UNIMPLEMENTED, /* 0x117 */ + UNIMPLEMENTED, /* 0x118 */ + UNIMPLEMENTED, /* 0x119 */ + UNIMPLEMENTED, /* 0x11a */ + UNIMPLEMENTED, /* 0x11b */ + UNIMPLEMENTED, /* 0x11c */ + UNIMPLEMENTED, /* 0x11d */ + UNIMPLEMENTED, /* 0x11e */ + UNIMPLEMENTED, /* 0x11f */ + UNIMPLEMENTED, /* 0x120 */ + UNIMPLEMENTED, /* 0x121 */ + UNIMPLEMENTED, /* 0x122 */ + UNIMPLEMENTED, /* 0x123 */ + UNIMPLEMENTED, /* 0x124 */ + UNIMPLEMENTED, /* 0x125 */ + UNIMPLEMENTED, /* 0x126 */ + UNIMPLEMENTED, /* 0x127 */ + UNIMPLEMENTED, /* 0x128 */ + UNIMPLEMENTED, /* 0x129 */ + UNIMPLEMENTED, /* 0x12a */ + UNIMPLEMENTED, /* 0x12b */ + UNIMPLEMENTED, /* 0x12c */ + UNIMPLEMENTED, /* 0x12d */ + UNIMPLEMENTED, /* 0x12e */ + UNIMPLEMENTED, /* 0x12f */ + UNIMPLEMENTED, /* 0x130 */ + UNIMPLEMENTED, /* 0x131 */ + UNIMPLEMENTED, /* 0x132 */ + UNIMPLEMENTED, /* 0x133 */ + UNIMPLEMENTED, /* 0x134 */ + UNIMPLEMENTED, /* 0x135 */ + UNIMPLEMENTED, /* 0x136 */ + UNIMPLEMENTED, /* 0x137 */ + UNIMPLEMENTED, /* 0x138 */ + UNIMPLEMENTED, /* 0x139 */ + UNIMPLEMENTED, /* 0x13a */ + UNIMPLEMENTED, /* 0x13b */ + UNIMPLEMENTED, /* 0x13c */ + UNIMPLEMENTED, /* 0x13d */ + UNIMPLEMENTED, /* 0x13e */ + UNIMPLEMENTED, /* 0x13f */ + UNIMPLEMENTED, /* 0x140 */ + UNIMPLEMENTED, /* 0x141 */ + UNIMPLEMENTED, /* 0x142 */ + UNIMPLEMENTED, /* 0x143 */ + UNIMPLEMENTED, /* 0x144 */ + UNIMPLEMENTED, /* 0x145 */ + UNIMPLEMENTED, /* 0x146 */ + UNIMPLEMENTED, /* 0x147 */ + UNIMPLEMENTED, /* 0x148 */ + UNIMPLEMENTED, /* 0x149 */ + UNIMPLEMENTED, /* 0x14a */ + UNIMPLEMENTED, /* 0x14b */ + UNIMPLEMENTED, /* 0x14c */ + UNIMPLEMENTED, /* 0x14d */ + UNIMPLEMENTED, /* 0x14e */ + UNIMPLEMENTED, /* 0x14f */ + UNIMPLEMENTED, /* 0x150 */ + UNIMPLEMENTED, /* 0x151 */ + UNIMPLEMENTED, /* 0x152 */ + UNIMPLEMENTED, /* 0x153 */ + UNIMPLEMENTED, /* 0x154 */ + UNIMPLEMENTED, /* 0x155 */ + UNIMPLEMENTED, /* 0x156 */ + UNIMPLEMENTED, /* 0x157 */ + UNIMPLEMENTED, /* 0x158 */ + UNIMPLEMENTED, /* 0x159 */ + UNIMPLEMENTED, /* 0x15a */ + UNIMPLEMENTED, /* 0x15b */ + UNIMPLEMENTED, /* 0x15c */ + UNIMPLEMENTED, /* 0x15d */ + UNIMPLEMENTED, /* 0x15e */ + UNIMPLEMENTED, /* 0x15f */ + UNIMPLEMENTED, /* 0x160 */ + UNIMPLEMENTED, /* 0x161 */ + UNIMPLEMENTED, /* 0x162 */ + UNIMPLEMENTED, /* 0x163 */ + UNIMPLEMENTED, /* 0x164 */ + UNIMPLEMENTED, /* 0x165 */ + UNIMPLEMENTED, /* 0x166 */ + UNIMPLEMENTED, /* 0x167 */ + UNIMPLEMENTED, /* 0x168 */ + UNIMPLEMENTED, /* 0x169 */ + UNIMPLEMENTED, /* 0x16a */ + UNIMPLEMENTED, /* 0x16b */ + UNIMPLEMENTED, /* 0x16c */ + UNIMPLEMENTED, /* 0x16d */ + UNIMPLEMENTED, /* 0x16e */ + UNIMPLEMENTED, /* 0x16f */ + FREG, /* 0x170 */ + FREG, /* 0x171 */ + FREG, /* 0x172 */ + FREG, /* 0x173 */ + FREG, /* 0x174 */ + FREG, /* 0x175 */ + FREG, /* 0x176 */ + FREG, /* 0x177 */ + FREG, /* 0x178 */ + FREG, /* 0x179 */ + FREG, /* 0x17a */ + FREG, /* 0x17b */ + FREG, /* 0x17c */ + FREG, /* 0x17d */ + FREG, /* 0x17e */ + FREG, /* 0x17f */ + + /* BANK 3 */ + + INDF, /* 0x180 */ + OPTION_REG, /* 0x181 */ + PCL, /* 0x182 */ + STATUS, /* 0x183 */ + FSR, /* 0x184 */ + SRCON, /* 0x185 */ + TRISB, /* 0x186 */ + BAUDCTL, /* 0x187 */ + ANSEL, /* 0x188 */ + ANSELH, /* 0x189 */ + PCLATH, /* 0x18a */ + INTCON, /* 0x18b */ + EECON1, /* 0x18c */ + EECON2, /* 0x18d */ + _RESERVED, /* 0x18e */ + _RESERVED, /* 0x18f */ + UNIMPLEMENTED, /* 0x190 */ + UNIMPLEMENTED, /* 0x191 */ + UNIMPLEMENTED, /* 0x192 */ + UNIMPLEMENTED, /* 0x193 */ + UNIMPLEMENTED, /* 0x194 */ + UNIMPLEMENTED, /* 0x195 */ + UNIMPLEMENTED, /* 0x196 */ + UNIMPLEMENTED, /* 0x197 */ + UNIMPLEMENTED, /* 0x198 */ + UNIMPLEMENTED, /* 0x199 */ + UNIMPLEMENTED, /* 0x19a */ + UNIMPLEMENTED, /* 0x19b */ + UNIMPLEMENTED, /* 0x19c */ + UNIMPLEMENTED, /* 0x19d */ + UNIMPLEMENTED, /* 0x19e */ + UNIMPLEMENTED, /* 0x19f */ + UNIMPLEMENTED, /* 0x1a0 */ + UNIMPLEMENTED, /* 0x1a1 */ + UNIMPLEMENTED, /* 0x1a2 */ + UNIMPLEMENTED, /* 0x1a3 */ + UNIMPLEMENTED, /* 0x1a4 */ + UNIMPLEMENTED, /* 0x1a5 */ + UNIMPLEMENTED, /* 0x1a6 */ + UNIMPLEMENTED, /* 0x1a7 */ + UNIMPLEMENTED, /* 0x1a8 */ + UNIMPLEMENTED, /* 0x1a9 */ + UNIMPLEMENTED, /* 0x1aa */ + UNIMPLEMENTED, /* 0x1ab */ + UNIMPLEMENTED, /* 0x1ac */ + UNIMPLEMENTED, /* 0x1ad */ + UNIMPLEMENTED, /* 0x1ae */ + UNIMPLEMENTED, /* 0x1af */ + UNIMPLEMENTED, /* 0x1b0 */ + UNIMPLEMENTED, /* 0x1b1 */ + UNIMPLEMENTED, /* 0x1b2 */ + UNIMPLEMENTED, /* 0x1b3 */ + UNIMPLEMENTED, /* 0x1b4 */ + UNIMPLEMENTED, /* 0x1b5 */ + UNIMPLEMENTED, /* 0x1b6 */ + UNIMPLEMENTED, /* 0x1b7 */ + UNIMPLEMENTED, /* 0x1b8 */ + UNIMPLEMENTED, /* 0x1b9 */ + UNIMPLEMENTED, /* 0x1ba */ + UNIMPLEMENTED, /* 0x1bb */ + UNIMPLEMENTED, /* 0x1bc */ + UNIMPLEMENTED, /* 0x1bd */ + UNIMPLEMENTED, /* 0x1be */ + UNIMPLEMENTED, /* 0x1bf */ + UNIMPLEMENTED, /* 0x1c0 */ + UNIMPLEMENTED, /* 0x1c1 */ + UNIMPLEMENTED, /* 0x1c2 */ + UNIMPLEMENTED, /* 0x1c3 */ + UNIMPLEMENTED, /* 0x1c4 */ + UNIMPLEMENTED, /* 0x1c5 */ + UNIMPLEMENTED, /* 0x1c6 */ + UNIMPLEMENTED, /* 0x1c7 */ + UNIMPLEMENTED, /* 0x1c8 */ + UNIMPLEMENTED, /* 0x1c9 */ + UNIMPLEMENTED, /* 0x1ca */ + UNIMPLEMENTED, /* 0x1cb */ + UNIMPLEMENTED, /* 0x1cc */ + UNIMPLEMENTED, /* 0x1cd */ + UNIMPLEMENTED, /* 0x1ce */ + UNIMPLEMENTED, /* 0x1cf */ + UNIMPLEMENTED, /* 0x1d0 */ + UNIMPLEMENTED, /* 0x1d1 */ + UNIMPLEMENTED, /* 0x1d2 */ + UNIMPLEMENTED, /* 0x1d3 */ + UNIMPLEMENTED, /* 0x1d4 */ + UNIMPLEMENTED, /* 0x1d5 */ + UNIMPLEMENTED, /* 0x1d6 */ + UNIMPLEMENTED, /* 0x1d7 */ + UNIMPLEMENTED, /* 0x1d8 */ + UNIMPLEMENTED, /* 0x1d9 */ + UNIMPLEMENTED, /* 0x1da */ + UNIMPLEMENTED, /* 0x1db */ + UNIMPLEMENTED, /* 0x1dc */ + UNIMPLEMENTED, /* 0x1dd */ + UNIMPLEMENTED, /* 0x1de */ + UNIMPLEMENTED, /* 0x1df */ + UNIMPLEMENTED, /* 0x1e0 */ + UNIMPLEMENTED, /* 0x1e1 */ + UNIMPLEMENTED, /* 0x1e2 */ + UNIMPLEMENTED, /* 0x1e3 */ + UNIMPLEMENTED, /* 0x1e4 */ + UNIMPLEMENTED, /* 0x1e5 */ + UNIMPLEMENTED, /* 0x1e6 */ + UNIMPLEMENTED, /* 0x1e7 */ + UNIMPLEMENTED, /* 0x1e8 */ + UNIMPLEMENTED, /* 0x1e9 */ + UNIMPLEMENTED, /* 0x1ea */ + UNIMPLEMENTED, /* 0x1eb */ + UNIMPLEMENTED, /* 0x1ec */ + UNIMPLEMENTED, /* 0x1ed */ + UNIMPLEMENTED, /* 0x1ee */ + UNIMPLEMENTED, /* 0x1ef */ + FREG, /* 0x1f0 */ + FREG, /* 0x1f1 */ + FREG, /* 0x1f2 */ + FREG, /* 0x1f3 */ + FREG, /* 0x1f4 */ + FREG, /* 0x1f5 */ + FREG, /* 0x1f6 */ + FREG, /* 0x1f7 */ + FREG, /* 0x1f8 */ + FREG, /* 0x1f9 */ + FREG, /* 0x1fa */ + FREG, /* 0x1fb */ + FREG, /* 0x1fc */ + FREG, /* 0x1fd */ + FREG, /* 0x1fe */ + FREG, /* 0x1ff */ +}; +// clang-format on + +#endif // RZ_PIC_MIDRANGE_PIC_MEMMAP_PIC16F882_H diff --git a/librz/arch/isa/pic/pic16f_memmaps/pic16f883_4.h b/librz/arch/isa/pic/pic16f_memmaps/pic16f883_4.h new file mode 100644 index 00000000000..97841336dd6 --- /dev/null +++ b/librz/arch/isa/pic/pic16f_memmaps/pic16f883_4.h @@ -0,0 +1,543 @@ +// SPDX-FileCopyrightText: 2023 Siddharth Mishra +// SPDX-License-Identifier: LGPL-3.0-only + +/** + * This file describes the memory map of PICF16883/4 device in PIC16F family. + * */ + +#ifndef RZ_PIC_MIDRANGE_PIC_MEMMAP_PIC16F883_H +#define RZ_PIC_MIDRANGE_PIC_MEMMAP_PIC16F883_H + +#include "regtypes.h" + +// clang-format off +PicMidrangeRegType pic16f883_reg_map[] = { + /* BANK 0 */ + INDF, /* 0x00 */ + TMR0, /* 0x01 */ + PCL, /* 0x02 */ + STATUS, /* 0x03 */ + FSR, /* 0x04 */ + PORTA, /* 0x05 */ + PORTB, /* 0x06 */ + PORTC, /* 0x07 */ + PORTD, /* 0x08 */ + PORTE, /* 0x09 */ + PCLATH, /* 0x0a */ + INTCON, /* 0x0b */ + PIR1, /* 0x0c */ + PIR2, /* 0x0d */ + TMR1L, /* 0x0e */ + TMR1H, /* 0x0f */ + T1CON, /* 0x10 */ + TMR2, /* 0x11 */ + T2CON, /* 0x12 */ + SSPBUF, /* 0x13 */ + SSPCON, /* 0x14 */ + CCPR1L, /* 0x15 */ + CCPR1H, /* 0x16 */ + CCP1CON, /* 0x17 */ + RCSTA, /* 0x18 */ + TXREG, /* 0x19 */ + RCREG, /* 0x1a */ + CCPR2L, /* 0x1b */ + CCPR2H, /* 0x1c */ + CCP2CON, /* 0x1d */ + ADRESH, /* 0x1e */ + ADCON0, /* 0x1f */ + FREG, /* 0x20 */ + FREG, /* 0x21 */ + FREG, /* 0x22 */ + FREG, /* 0x23 */ + FREG, /* 0x24 */ + FREG, /* 0x25 */ + FREG, /* 0x26 */ + FREG, /* 0x27 */ + FREG, /* 0x28 */ + FREG, /* 0x29 */ + FREG, /* 0x2a */ + FREG, /* 0x2b */ + FREG, /* 0x2c */ + FREG, /* 0x2d */ + FREG, /* 0x2e */ + FREG, /* 0x2f */ + FREG, /* 0x30 */ + FREG, /* 0x31 */ + FREG, /* 0x32 */ + FREG, /* 0x33 */ + FREG, /* 0x34 */ + FREG, /* 0x35 */ + FREG, /* 0x36 */ + FREG, /* 0x37 */ + FREG, /* 0x38 */ + FREG, /* 0x39 */ + FREG, /* 0x3a */ + FREG, /* 0x3b */ + FREG, /* 0x3c */ + FREG, /* 0x3d */ + FREG, /* 0x3e */ + FREG, /* 0x3f */ + FREG, /* 0x40 */ + FREG, /* 0x41 */ + FREG, /* 0x42 */ + FREG, /* 0x43 */ + FREG, /* 0x44 */ + FREG, /* 0x45 */ + FREG, /* 0x46 */ + FREG, /* 0x47 */ + FREG, /* 0x48 */ + FREG, /* 0x49 */ + FREG, /* 0x4a */ + FREG, /* 0x4b */ + FREG, /* 0x4c */ + FREG, /* 0x4d */ + FREG, /* 0x4e */ + FREG, /* 0x4f */ + FREG, /* 0x50 */ + FREG, /* 0x51 */ + FREG, /* 0x52 */ + FREG, /* 0x53 */ + FREG, /* 0x54 */ + FREG, /* 0x55 */ + FREG, /* 0x56 */ + FREG, /* 0x57 */ + FREG, /* 0x58 */ + FREG, /* 0x59 */ + FREG, /* 0x5a */ + FREG, /* 0x5b */ + FREG, /* 0x5c */ + FREG, /* 0x5d */ + FREG, /* 0x5e */ + FREG, /* 0x5f */ + FREG, /* 0x60 */ + FREG, /* 0x61 */ + FREG, /* 0x62 */ + FREG, /* 0x63 */ + FREG, /* 0x64 */ + FREG, /* 0x65 */ + FREG, /* 0x66 */ + FREG, /* 0x67 */ + FREG, /* 0x68 */ + FREG, /* 0x69 */ + FREG, /* 0x6a */ + FREG, /* 0x6b */ + FREG, /* 0x6c */ + FREG, /* 0x6d */ + FREG, /* 0x6e */ + FREG, /* 0x6f */ + FREG, /* 0x70 */ + FREG, /* 0x71 */ + FREG, /* 0x72 */ + FREG, /* 0x73 */ + FREG, /* 0x74 */ + FREG, /* 0x75 */ + FREG, /* 0x76 */ + FREG, /* 0x77 */ + FREG, /* 0x78 */ + FREG, /* 0x79 */ + FREG, /* 0x7a */ + FREG, /* 0x7b */ + FREG, /* 0x7c */ + FREG, /* 0x7d */ + FREG, /* 0x7e */ + FREG, /* 0x7f */ + + /* BANK1 */ + + INDF, /* 0x80 */ + OPTION_REG, /* 0x81 */ + PCL, /* 0x82 */ + STATUS, /* 0x83 */ + FSR, /* 0x84 */ + TRISA, /* 0x85 */ + TRISB, /* 0x86 */ + TRISC, /* 0x87 */ + TRISD, /* 0x88 */ + TRISE, /* 0x89 */ + PCLATH, /* 0x8a */ + INTCON, /* 0x8b */ + PIE1, /* 0x8c */ + PIE2, /* 0x8d */ + PCON, /* 0x8e */ + OSCCON, /* 0x8f */ + OSCTUNE, /* 0x90 */ + SSPCON2, /* 0x91 */ + PR2, /* 0x92 */ + SSPADD, /* 0x93 */ + SSPSTAT, /* 0x94 */ + WPUB, /* 0x95 */ + IOCB, /* 0x96 */ + VRCON, /* 0x97 */ + TXSTA, /* 0x98 */ + SPBRG, /* 0x99 */ + SPBRGH, /* 0x9a */ + PWM1CON, /* 0x9b */ + ECCPAS, /* 0x9c */ + PSTRCON, /* 0x9d */ + ADRESL, /* 0x9e */ + ADCON1, /* 0x9f */ + FREG, /* 0xa0 */ + FREG, /* 0xa1 */ + FREG, /* 0xa2 */ + FREG, /* 0xa3 */ + FREG, /* 0xa4 */ + FREG, /* 0xa5 */ + FREG, /* 0xa6 */ + FREG, /* 0xa7 */ + FREG, /* 0xa8 */ + FREG, /* 0xa9 */ + FREG, /* 0xaa */ + FREG, /* 0xab */ + FREG, /* 0xac */ + FREG, /* 0xad */ + FREG, /* 0xae */ + FREG, /* 0xaf */ + FREG, /* 0xb0 */ + FREG, /* 0xb1 */ + FREG, /* 0xb2 */ + FREG, /* 0xb3 */ + FREG, /* 0xb4 */ + FREG, /* 0xb5 */ + FREG, /* 0xb6 */ + FREG, /* 0xb7 */ + FREG, /* 0xb8 */ + FREG, /* 0xb9 */ + FREG, /* 0xba */ + FREG, /* 0xbb */ + FREG, /* 0xbc */ + FREG, /* 0xbd */ + FREG, /* 0xbe */ + FREG, /* 0xbf */ + FREG, /* 0xc0 */ + FREG, /* 0xc1 */ + FREG, /* 0xc2 */ + FREG, /* 0xc3 */ + FREG, /* 0xc4 */ + FREG, /* 0xc5 */ + FREG, /* 0xc6 */ + FREG, /* 0xc7 */ + FREG, /* 0xc8 */ + FREG, /* 0xc9 */ + FREG, /* 0xca */ + FREG, /* 0xcb */ + FREG, /* 0xcc */ + FREG, /* 0xcd */ + FREG, /* 0xce */ + FREG, /* 0xcf */ + FREG, /* 0xd0 */ + FREG, /* 0xd1 */ + FREG, /* 0xd2 */ + FREG, /* 0xd3 */ + FREG, /* 0xd4 */ + FREG, /* 0xd5 */ + FREG, /* 0xd6 */ + FREG, /* 0xd7 */ + FREG, /* 0xd8 */ + FREG, /* 0xd9 */ + FREG, /* 0xda */ + FREG, /* 0xdb */ + FREG, /* 0xdc */ + FREG, /* 0xdd */ + FREG, /* 0xde */ + FREG, /* 0xdf */ + FREG, /* 0xe0 */ + FREG, /* 0xe1 */ + FREG, /* 0xe2 */ + FREG, /* 0xe3 */ + FREG, /* 0xe4 */ + FREG, /* 0xe5 */ + FREG, /* 0xe6 */ + FREG, /* 0xe7 */ + FREG, /* 0xe8 */ + FREG, /* 0xe9 */ + FREG, /* 0xea */ + FREG, /* 0xeb */ + FREG, /* 0xec */ + FREG, /* 0xed */ + FREG, /* 0xee */ + FREG, /* 0xef */ + FREG, /* 0xf0 */ + FREG, /* 0xf1 */ + FREG, /* 0xf2 */ + FREG, /* 0xf3 */ + FREG, /* 0xf4 */ + FREG, /* 0xf5 */ + FREG, /* 0xf6 */ + FREG, /* 0xf7 */ + FREG, /* 0xf8 */ + FREG, /* 0xf9 */ + FREG, /* 0xfa */ + FREG, /* 0xfb */ + FREG, /* 0xfc */ + FREG, /* 0xfd */ + FREG, /* 0xfe */ + FREG, /* 0xff */ + + /* BANK 2 */ + + INDF, /* 0x100 */ + TMR0, /* 0x101 */ + PCL, /* 0x102 */ + STATUS, /* 0x103 */ + FSR, /* 0x104 */ + WDTCON, /* 0x105 */ + PORTB, /* 0x106 */ + CM1CON0, /* 0x107 */ + CM2CON0, /* 0x108 */ + CM2CON1, /* 0x109 */ + PCLATH, /* 0x10a */ + INTCON, /* 0x10b */ + EEDAT, /* 0x10c */ + EEADR, /* 0x10d */ + EEDATH, /* 0x10e */ + EEADRH, /* 0x10f */ + UNIMPLEMENTED, /* 0x110 */ + UNIMPLEMENTED, /* 0x111 */ + UNIMPLEMENTED, /* 0x112 */ + UNIMPLEMENTED, /* 0x113 */ + UNIMPLEMENTED, /* 0x114 */ + UNIMPLEMENTED, /* 0x115 */ + UNIMPLEMENTED, /* 0x116 */ + UNIMPLEMENTED, /* 0x117 */ + UNIMPLEMENTED, /* 0x118 */ + UNIMPLEMENTED, /* 0x119 */ + UNIMPLEMENTED, /* 0x11a */ + UNIMPLEMENTED, /* 0x11b */ + UNIMPLEMENTED, /* 0x11c */ + UNIMPLEMENTED, /* 0x11d */ + UNIMPLEMENTED, /* 0x11e */ + UNIMPLEMENTED, /* 0x11f */ + FREG, /* 0x120 */ + FREG, /* 0x121 */ + FREG, /* 0x122 */ + FREG, /* 0x123 */ + FREG, /* 0x124 */ + FREG, /* 0x125 */ + FREG, /* 0x126 */ + FREG, /* 0x127 */ + FREG, /* 0x128 */ + FREG, /* 0x129 */ + FREG, /* 0x12a */ + FREG, /* 0x12b */ + FREG, /* 0x12c */ + FREG, /* 0x12d */ + FREG, /* 0x12e */ + FREG, /* 0x12f */ + FREG, /* 0x130 */ + FREG, /* 0x131 */ + FREG, /* 0x132 */ + FREG, /* 0x133 */ + FREG, /* 0x134 */ + FREG, /* 0x135 */ + FREG, /* 0x136 */ + FREG, /* 0x137 */ + FREG, /* 0x138 */ + FREG, /* 0x139 */ + FREG, /* 0x13a */ + FREG, /* 0x13b */ + FREG, /* 0x13c */ + FREG, /* 0x13d */ + FREG, /* 0x13e */ + FREG, /* 0x13f */ + FREG, /* 0x140 */ + FREG, /* 0x141 */ + FREG, /* 0x142 */ + FREG, /* 0x143 */ + FREG, /* 0x144 */ + FREG, /* 0x145 */ + FREG, /* 0x146 */ + FREG, /* 0x147 */ + FREG, /* 0x148 */ + FREG, /* 0x149 */ + FREG, /* 0x14a */ + FREG, /* 0x14b */ + FREG, /* 0x14c */ + FREG, /* 0x14d */ + FREG, /* 0x14e */ + FREG, /* 0x14f */ + FREG, /* 0x150 */ + FREG, /* 0x151 */ + FREG, /* 0x152 */ + FREG, /* 0x153 */ + FREG, /* 0x154 */ + FREG, /* 0x155 */ + FREG, /* 0x156 */ + FREG, /* 0x157 */ + FREG, /* 0x158 */ + FREG, /* 0x159 */ + FREG, /* 0x15a */ + FREG, /* 0x15b */ + FREG, /* 0x15c */ + FREG, /* 0x15d */ + FREG, /* 0x15e */ + FREG, /* 0x15f */ + FREG, /* 0x160 */ + FREG, /* 0x161 */ + FREG, /* 0x162 */ + FREG, /* 0x163 */ + FREG, /* 0x164 */ + FREG, /* 0x165 */ + FREG, /* 0x166 */ + FREG, /* 0x167 */ + FREG, /* 0x168 */ + FREG, /* 0x169 */ + FREG, /* 0x16a */ + FREG, /* 0x16b */ + FREG, /* 0x16c */ + FREG, /* 0x16d */ + FREG, /* 0x16e */ + FREG, /* 0x16f */ + FREG, /* 0x170 */ + FREG, /* 0x171 */ + FREG, /* 0x172 */ + FREG, /* 0x173 */ + FREG, /* 0x174 */ + FREG, /* 0x175 */ + FREG, /* 0x176 */ + FREG, /* 0x177 */ + FREG, /* 0x178 */ + FREG, /* 0x179 */ + FREG, /* 0x17a */ + FREG, /* 0x17b */ + FREG, /* 0x17c */ + FREG, /* 0x17d */ + FREG, /* 0x17e */ + FREG, /* 0x17f */ + + /* BANK 3 */ + + INDF, /* 0x180 */ + OPTION_REG, /* 0x181 */ + PCL, /* 0x182 */ + STATUS, /* 0x183 */ + FSR, /* 0x184 */ + SRCON, /* 0x185 */ + TRISB, /* 0x186 */ + BAUDCTL, /* 0x187 */ + ANSEL, /* 0x188 */ + ANSELH, /* 0x189 */ + PCLATH, /* 0x18a */ + INTCON, /* 0x18b */ + EECON1, /* 0x18c */ + EECON2, /* 0x18d */ + _RESERVED, /* 0x18e */ + _RESERVED, /* 0x18f */ + UNIMPLEMENTED, /* 0x190 */ + UNIMPLEMENTED, /* 0x191 */ + UNIMPLEMENTED, /* 0x192 */ + UNIMPLEMENTED, /* 0x193 */ + UNIMPLEMENTED, /* 0x194 */ + UNIMPLEMENTED, /* 0x195 */ + UNIMPLEMENTED, /* 0x196 */ + UNIMPLEMENTED, /* 0x197 */ + UNIMPLEMENTED, /* 0x198 */ + UNIMPLEMENTED, /* 0x199 */ + UNIMPLEMENTED, /* 0x19a */ + UNIMPLEMENTED, /* 0x19b */ + UNIMPLEMENTED, /* 0x19c */ + UNIMPLEMENTED, /* 0x19d */ + UNIMPLEMENTED, /* 0x19e */ + UNIMPLEMENTED, /* 0x19f */ + UNIMPLEMENTED, /* 0x1a0 */ + UNIMPLEMENTED, /* 0x1a1 */ + UNIMPLEMENTED, /* 0x1a2 */ + UNIMPLEMENTED, /* 0x1a3 */ + UNIMPLEMENTED, /* 0x1a4 */ + UNIMPLEMENTED, /* 0x1a5 */ + UNIMPLEMENTED, /* 0x1a6 */ + UNIMPLEMENTED, /* 0x1a7 */ + UNIMPLEMENTED, /* 0x1a8 */ + UNIMPLEMENTED, /* 0x1a9 */ + UNIMPLEMENTED, /* 0x1aa */ + UNIMPLEMENTED, /* 0x1ab */ + UNIMPLEMENTED, /* 0x1ac */ + UNIMPLEMENTED, /* 0x1ad */ + UNIMPLEMENTED, /* 0x1ae */ + UNIMPLEMENTED, /* 0x1af */ + UNIMPLEMENTED, /* 0x1b0 */ + UNIMPLEMENTED, /* 0x1b1 */ + UNIMPLEMENTED, /* 0x1b2 */ + UNIMPLEMENTED, /* 0x1b3 */ + UNIMPLEMENTED, /* 0x1b4 */ + UNIMPLEMENTED, /* 0x1b5 */ + UNIMPLEMENTED, /* 0x1b6 */ + UNIMPLEMENTED, /* 0x1b7 */ + UNIMPLEMENTED, /* 0x1b8 */ + UNIMPLEMENTED, /* 0x1b9 */ + UNIMPLEMENTED, /* 0x1ba */ + UNIMPLEMENTED, /* 0x1bb */ + UNIMPLEMENTED, /* 0x1bc */ + UNIMPLEMENTED, /* 0x1bd */ + UNIMPLEMENTED, /* 0x1be */ + UNIMPLEMENTED, /* 0x1bf */ + UNIMPLEMENTED, /* 0x1c0 */ + UNIMPLEMENTED, /* 0x1c1 */ + UNIMPLEMENTED, /* 0x1c2 */ + UNIMPLEMENTED, /* 0x1c3 */ + UNIMPLEMENTED, /* 0x1c4 */ + UNIMPLEMENTED, /* 0x1c5 */ + UNIMPLEMENTED, /* 0x1c6 */ + UNIMPLEMENTED, /* 0x1c7 */ + UNIMPLEMENTED, /* 0x1c8 */ + UNIMPLEMENTED, /* 0x1c9 */ + UNIMPLEMENTED, /* 0x1ca */ + UNIMPLEMENTED, /* 0x1cb */ + UNIMPLEMENTED, /* 0x1cc */ + UNIMPLEMENTED, /* 0x1cd */ + UNIMPLEMENTED, /* 0x1ce */ + UNIMPLEMENTED, /* 0x1cf */ + UNIMPLEMENTED, /* 0x1d0 */ + UNIMPLEMENTED, /* 0x1d1 */ + UNIMPLEMENTED, /* 0x1d2 */ + UNIMPLEMENTED, /* 0x1d3 */ + UNIMPLEMENTED, /* 0x1d4 */ + UNIMPLEMENTED, /* 0x1d5 */ + UNIMPLEMENTED, /* 0x1d6 */ + UNIMPLEMENTED, /* 0x1d7 */ + UNIMPLEMENTED, /* 0x1d8 */ + UNIMPLEMENTED, /* 0x1d9 */ + UNIMPLEMENTED, /* 0x1da */ + UNIMPLEMENTED, /* 0x1db */ + UNIMPLEMENTED, /* 0x1dc */ + UNIMPLEMENTED, /* 0x1dd */ + UNIMPLEMENTED, /* 0x1de */ + UNIMPLEMENTED, /* 0x1df */ + UNIMPLEMENTED, /* 0x1e0 */ + UNIMPLEMENTED, /* 0x1e1 */ + UNIMPLEMENTED, /* 0x1e2 */ + UNIMPLEMENTED, /* 0x1e3 */ + UNIMPLEMENTED, /* 0x1e4 */ + UNIMPLEMENTED, /* 0x1e5 */ + UNIMPLEMENTED, /* 0x1e6 */ + UNIMPLEMENTED, /* 0x1e7 */ + UNIMPLEMENTED, /* 0x1e8 */ + UNIMPLEMENTED, /* 0x1e9 */ + UNIMPLEMENTED, /* 0x1ea */ + UNIMPLEMENTED, /* 0x1eb */ + UNIMPLEMENTED, /* 0x1ec */ + UNIMPLEMENTED, /* 0x1ed */ + UNIMPLEMENTED, /* 0x1ee */ + UNIMPLEMENTED, /* 0x1ef */ + FREG, /* 0x1f0 */ + FREG, /* 0x1f1 */ + FREG, /* 0x1f2 */ + FREG, /* 0x1f3 */ + FREG, /* 0x1f4 */ + FREG, /* 0x1f5 */ + FREG, /* 0x1f6 */ + FREG, /* 0x1f7 */ + FREG, /* 0x1f8 */ + FREG, /* 0x1f9 */ + FREG, /* 0x1fa */ + FREG, /* 0x1fb */ + FREG, /* 0x1fc */ + FREG, /* 0x1fd */ + FREG, /* 0x1fe */ + FREG, /* 0x1ff */ +}; +// clang-format on + +// memory map for PIC16F883 and PIC16F884 are same +PicMidrangeRegType *pic16f884_reg_map = pic16f883_reg_map; + +#endif // RZ_PIC_MIDRANGE_PIC_MEMMAP_PIC16F882_H diff --git a/librz/arch/isa/pic/pic16f_memmaps/pic16f886_7.h b/librz/arch/isa/pic/pic16f_memmaps/pic16f886_7.h new file mode 100644 index 00000000000..e9c77efce5f --- /dev/null +++ b/librz/arch/isa/pic/pic16f_memmaps/pic16f886_7.h @@ -0,0 +1,543 @@ +// SPDX-FileCopyrightText: 2023 Siddharth Mishra +// SPDX-License-Identifier: LGPL-3.0-only + +/** + * This file describes the memory map of PICF16886/7 device in PIC16F family. + * */ + +#ifndef RZ_PIC_MIDRANGE_PIC_MEMMAP_PIC16F886_H +#define RZ_PIC_MIDRANGE_PIC_MEMMAP_PIC16F886_H + +#include "regtypes.h" + +// clang-format off +PicMidrangeRegType pic16f886_reg_map[] = { + /* BANK 0 */ + INDF, /* 0x00 */ + TMR0, /* 0x01 */ + PCL, /* 0x02 */ + STATUS, /* 0x03 */ + FSR, /* 0x04 */ + PORTA, /* 0x05 */ + PORTB, /* 0x06 */ + PORTC, /* 0x07 */ + PORTD, /* 0x08 */ + PORTE, /* 0x09 */ + PCLATH, /* 0x0a */ + INTCON, /* 0x0b */ + PIR1, /* 0x0c */ + PIR2, /* 0x0d */ + TMR1L, /* 0x0e */ + TMR1H, /* 0x0f */ + T1CON, /* 0x10 */ + TMR2, /* 0x11 */ + T2CON, /* 0x12 */ + SSPBUF, /* 0x13 */ + SSPCON, /* 0x14 */ + CCPR1L, /* 0x15 */ + CCPR1H, /* 0x16 */ + CCP1CON, /* 0x17 */ + RCSTA, /* 0x18 */ + TXREG, /* 0x19 */ + RCREG, /* 0x1a */ + CCPR2L, /* 0x1b */ + CCPR2H, /* 0x1c */ + CCP2CON, /* 0x1d */ + ADRESH, /* 0x1e */ + ADCON0, /* 0x1f */ + FREG, /* 0x20 */ + FREG, /* 0x21 */ + FREG, /* 0x22 */ + FREG, /* 0x23 */ + FREG, /* 0x24 */ + FREG, /* 0x25 */ + FREG, /* 0x26 */ + FREG, /* 0x27 */ + FREG, /* 0x28 */ + FREG, /* 0x29 */ + FREG, /* 0x2a */ + FREG, /* 0x2b */ + FREG, /* 0x2c */ + FREG, /* 0x2d */ + FREG, /* 0x2e */ + FREG, /* 0x2f */ + FREG, /* 0x30 */ + FREG, /* 0x31 */ + FREG, /* 0x32 */ + FREG, /* 0x33 */ + FREG, /* 0x34 */ + FREG, /* 0x35 */ + FREG, /* 0x36 */ + FREG, /* 0x37 */ + FREG, /* 0x38 */ + FREG, /* 0x39 */ + FREG, /* 0x3a */ + FREG, /* 0x3b */ + FREG, /* 0x3c */ + FREG, /* 0x3d */ + FREG, /* 0x3e */ + FREG, /* 0x3f */ + FREG, /* 0x40 */ + FREG, /* 0x41 */ + FREG, /* 0x42 */ + FREG, /* 0x43 */ + FREG, /* 0x44 */ + FREG, /* 0x45 */ + FREG, /* 0x46 */ + FREG, /* 0x47 */ + FREG, /* 0x48 */ + FREG, /* 0x49 */ + FREG, /* 0x4a */ + FREG, /* 0x4b */ + FREG, /* 0x4c */ + FREG, /* 0x4d */ + FREG, /* 0x4e */ + FREG, /* 0x4f */ + FREG, /* 0x50 */ + FREG, /* 0x51 */ + FREG, /* 0x52 */ + FREG, /* 0x53 */ + FREG, /* 0x54 */ + FREG, /* 0x55 */ + FREG, /* 0x56 */ + FREG, /* 0x57 */ + FREG, /* 0x58 */ + FREG, /* 0x59 */ + FREG, /* 0x5a */ + FREG, /* 0x5b */ + FREG, /* 0x5c */ + FREG, /* 0x5d */ + FREG, /* 0x5e */ + FREG, /* 0x5f */ + FREG, /* 0x60 */ + FREG, /* 0x61 */ + FREG, /* 0x62 */ + FREG, /* 0x63 */ + FREG, /* 0x64 */ + FREG, /* 0x65 */ + FREG, /* 0x66 */ + FREG, /* 0x67 */ + FREG, /* 0x68 */ + FREG, /* 0x69 */ + FREG, /* 0x6a */ + FREG, /* 0x6b */ + FREG, /* 0x6c */ + FREG, /* 0x6d */ + FREG, /* 0x6e */ + FREG, /* 0x6f */ + FREG, /* 0x70 */ + FREG, /* 0x71 */ + FREG, /* 0x72 */ + FREG, /* 0x73 */ + FREG, /* 0x74 */ + FREG, /* 0x75 */ + FREG, /* 0x76 */ + FREG, /* 0x77 */ + FREG, /* 0x78 */ + FREG, /* 0x79 */ + FREG, /* 0x7a */ + FREG, /* 0x7b */ + FREG, /* 0x7c */ + FREG, /* 0x7d */ + FREG, /* 0x7e */ + FREG, /* 0x7f */ + + /* BANK1 */ + + INDF, /* 0x80 */ + OPTION_REG, /* 0x81 */ + PCL, /* 0x82 */ + STATUS, /* 0x83 */ + FSR, /* 0x84 */ + TRISA, /* 0x85 */ + TRISB, /* 0x86 */ + TRISC, /* 0x87 */ + TRISD, /* 0x88 */ + TRISE, /* 0x89 */ + PCLATH, /* 0x8a */ + INTCON, /* 0x8b */ + PIE1, /* 0x8c */ + PIE2, /* 0x8d */ + PCON, /* 0x8e */ + OSCCON, /* 0x8f */ + OSCTUNE, /* 0x90 */ + SSPCON2, /* 0x91 */ + PR2, /* 0x92 */ + SSPADD, /* 0x93 */ + SSPSTAT, /* 0x94 */ + WPUB, /* 0x95 */ + IOCB, /* 0x96 */ + VRCON, /* 0x97 */ + TXSTA, /* 0x98 */ + SPBRG, /* 0x99 */ + SPBRGH, /* 0x9a */ + PWM1CON, /* 0x9b */ + ECCPAS, /* 0x9c */ + PSTRCON, /* 0x9d */ + ADRESL, /* 0x9e */ + ADCON1, /* 0x9f */ + FREG, /* 0xa0 */ + FREG, /* 0xa1 */ + FREG, /* 0xa2 */ + FREG, /* 0xa3 */ + FREG, /* 0xa4 */ + FREG, /* 0xa5 */ + FREG, /* 0xa6 */ + FREG, /* 0xa7 */ + FREG, /* 0xa8 */ + FREG, /* 0xa9 */ + FREG, /* 0xaa */ + FREG, /* 0xab */ + FREG, /* 0xac */ + FREG, /* 0xad */ + FREG, /* 0xae */ + FREG, /* 0xaf */ + FREG, /* 0xb0 */ + FREG, /* 0xb1 */ + FREG, /* 0xb2 */ + FREG, /* 0xb3 */ + FREG, /* 0xb4 */ + FREG, /* 0xb5 */ + FREG, /* 0xb6 */ + FREG, /* 0xb7 */ + FREG, /* 0xb8 */ + FREG, /* 0xb9 */ + FREG, /* 0xba */ + FREG, /* 0xbb */ + FREG, /* 0xbc */ + FREG, /* 0xbd */ + FREG, /* 0xbe */ + FREG, /* 0xbf */ + FREG, /* 0xc0 */ + FREG, /* 0xc1 */ + FREG, /* 0xc2 */ + FREG, /* 0xc3 */ + FREG, /* 0xc4 */ + FREG, /* 0xc5 */ + FREG, /* 0xc6 */ + FREG, /* 0xc7 */ + FREG, /* 0xc8 */ + FREG, /* 0xc9 */ + FREG, /* 0xca */ + FREG, /* 0xcb */ + FREG, /* 0xcc */ + FREG, /* 0xcd */ + FREG, /* 0xce */ + FREG, /* 0xcf */ + FREG, /* 0xd0 */ + FREG, /* 0xd1 */ + FREG, /* 0xd2 */ + FREG, /* 0xd3 */ + FREG, /* 0xd4 */ + FREG, /* 0xd5 */ + FREG, /* 0xd6 */ + FREG, /* 0xd7 */ + FREG, /* 0xd8 */ + FREG, /* 0xd9 */ + FREG, /* 0xda */ + FREG, /* 0xdb */ + FREG, /* 0xdc */ + FREG, /* 0xdd */ + FREG, /* 0xde */ + FREG, /* 0xdf */ + FREG, /* 0xe0 */ + FREG, /* 0xe1 */ + FREG, /* 0xe2 */ + FREG, /* 0xe3 */ + FREG, /* 0xe4 */ + FREG, /* 0xe5 */ + FREG, /* 0xe6 */ + FREG, /* 0xe7 */ + FREG, /* 0xe8 */ + FREG, /* 0xe9 */ + FREG, /* 0xea */ + FREG, /* 0xeb */ + FREG, /* 0xec */ + FREG, /* 0xed */ + FREG, /* 0xee */ + FREG, /* 0xef */ + FREG, /* 0xf0 */ + FREG, /* 0xf1 */ + FREG, /* 0xf2 */ + FREG, /* 0xf3 */ + FREG, /* 0xf4 */ + FREG, /* 0xf5 */ + FREG, /* 0xf6 */ + FREG, /* 0xf7 */ + FREG, /* 0xf8 */ + FREG, /* 0xf9 */ + FREG, /* 0xfa */ + FREG, /* 0xfb */ + FREG, /* 0xfc */ + FREG, /* 0xfd */ + FREG, /* 0xfe */ + FREG, /* 0xff */ + + /* BANK 2 */ + + INDF, /* 0x100 */ + TMR0, /* 0x101 */ + PCL, /* 0x102 */ + STATUS, /* 0x103 */ + FSR, /* 0x104 */ + WDTCON, /* 0x105 */ + PORTB, /* 0x106 */ + CM1CON0, /* 0x107 */ + CM2CON0, /* 0x108 */ + CM2CON1, /* 0x109 */ + PCLATH, /* 0x10a */ + INTCON, /* 0x10b */ + EEDAT, /* 0x10c */ + EEADR, /* 0x10d */ + EEDATH, /* 0x10e */ + EEADRH, /* 0x10f */ + FREG, /* 0x110 */ + FREG, /* 0x111 */ + FREG, /* 0x112 */ + FREG, /* 0x113 */ + FREG, /* 0x114 */ + FREG, /* 0x115 */ + FREG, /* 0x116 */ + FREG, /* 0x117 */ + FREG, /* 0x118 */ + FREG, /* 0x119 */ + FREG, /* 0x11a */ + FREG, /* 0x11b */ + FREG, /* 0x11c */ + FREG, /* 0x11d */ + FREG, /* 0x11e */ + FREG, /* 0x11f */ + FREG, /* 0x120 */ + FREG, /* 0x121 */ + FREG, /* 0x122 */ + FREG, /* 0x123 */ + FREG, /* 0x124 */ + FREG, /* 0x125 */ + FREG, /* 0x126 */ + FREG, /* 0x127 */ + FREG, /* 0x128 */ + FREG, /* 0x129 */ + FREG, /* 0x12a */ + FREG, /* 0x12b */ + FREG, /* 0x12c */ + FREG, /* 0x12d */ + FREG, /* 0x12e */ + FREG, /* 0x12f */ + FREG, /* 0x130 */ + FREG, /* 0x131 */ + FREG, /* 0x132 */ + FREG, /* 0x133 */ + FREG, /* 0x134 */ + FREG, /* 0x135 */ + FREG, /* 0x136 */ + FREG, /* 0x137 */ + FREG, /* 0x138 */ + FREG, /* 0x139 */ + FREG, /* 0x13a */ + FREG, /* 0x13b */ + FREG, /* 0x13c */ + FREG, /* 0x13d */ + FREG, /* 0x13e */ + FREG, /* 0x13f */ + FREG, /* 0x140 */ + FREG, /* 0x141 */ + FREG, /* 0x142 */ + FREG, /* 0x143 */ + FREG, /* 0x144 */ + FREG, /* 0x145 */ + FREG, /* 0x146 */ + FREG, /* 0x147 */ + FREG, /* 0x148 */ + FREG, /* 0x149 */ + FREG, /* 0x14a */ + FREG, /* 0x14b */ + FREG, /* 0x14c */ + FREG, /* 0x14d */ + FREG, /* 0x14e */ + FREG, /* 0x14f */ + FREG, /* 0x150 */ + FREG, /* 0x151 */ + FREG, /* 0x152 */ + FREG, /* 0x153 */ + FREG, /* 0x154 */ + FREG, /* 0x155 */ + FREG, /* 0x156 */ + FREG, /* 0x157 */ + FREG, /* 0x158 */ + FREG, /* 0x159 */ + FREG, /* 0x15a */ + FREG, /* 0x15b */ + FREG, /* 0x15c */ + FREG, /* 0x15d */ + FREG, /* 0x15e */ + FREG, /* 0x15f */ + FREG, /* 0x160 */ + FREG, /* 0x161 */ + FREG, /* 0x162 */ + FREG, /* 0x163 */ + FREG, /* 0x164 */ + FREG, /* 0x165 */ + FREG, /* 0x166 */ + FREG, /* 0x167 */ + FREG, /* 0x168 */ + FREG, /* 0x169 */ + FREG, /* 0x16a */ + FREG, /* 0x16b */ + FREG, /* 0x16c */ + FREG, /* 0x16d */ + FREG, /* 0x16e */ + FREG, /* 0x16f */ + FREG, /* 0x170 */ + FREG, /* 0x171 */ + FREG, /* 0x172 */ + FREG, /* 0x173 */ + FREG, /* 0x174 */ + FREG, /* 0x175 */ + FREG, /* 0x176 */ + FREG, /* 0x177 */ + FREG, /* 0x178 */ + FREG, /* 0x179 */ + FREG, /* 0x17a */ + FREG, /* 0x17b */ + FREG, /* 0x17c */ + FREG, /* 0x17d */ + FREG, /* 0x17e */ + FREG, /* 0x17f */ + + /* BANK 3 */ + + INDF, /* 0x180 */ + OPTION_REG, /* 0x181 */ + PCL, /* 0x182 */ + STATUS, /* 0x183 */ + FSR, /* 0x184 */ + SRCON, /* 0x185 */ + TRISB, /* 0x186 */ + BAUDCTL, /* 0x187 */ + ANSEL, /* 0x188 */ + ANSELH, /* 0x189 */ + PCLATH, /* 0x18a */ + INTCON, /* 0x18b */ + EECON1, /* 0x18c */ + EECON2, /* 0x18d */ + _RESERVED, /* 0x18e */ + _RESERVED, /* 0x18f */ + FREG, /* 0x190 */ + FREG, /* 0x191 */ + FREG, /* 0x192 */ + FREG, /* 0x193 */ + FREG, /* 0x194 */ + FREG, /* 0x195 */ + FREG, /* 0x196 */ + FREG, /* 0x197 */ + FREG, /* 0x198 */ + FREG, /* 0x199 */ + FREG, /* 0x19a */ + FREG, /* 0x19b */ + FREG, /* 0x19c */ + FREG, /* 0x19d */ + FREG, /* 0x19e */ + FREG, /* 0x19f */ + FREG, /* 0x1a0 */ + FREG, /* 0x1a1 */ + FREG, /* 0x1a2 */ + FREG, /* 0x1a3 */ + FREG, /* 0x1a4 */ + FREG, /* 0x1a5 */ + FREG, /* 0x1a6 */ + FREG, /* 0x1a7 */ + FREG, /* 0x1a8 */ + FREG, /* 0x1a9 */ + FREG, /* 0x1aa */ + FREG, /* 0x1ab */ + FREG, /* 0x1ac */ + FREG, /* 0x1ad */ + FREG, /* 0x1ae */ + FREG, /* 0x1af */ + FREG, /* 0x1b0 */ + FREG, /* 0x1b1 */ + FREG, /* 0x1b2 */ + FREG, /* 0x1b3 */ + FREG, /* 0x1b4 */ + FREG, /* 0x1b5 */ + FREG, /* 0x1b6 */ + FREG, /* 0x1b7 */ + FREG, /* 0x1b8 */ + FREG, /* 0x1b9 */ + FREG, /* 0x1ba */ + FREG, /* 0x1bb */ + FREG, /* 0x1bc */ + FREG, /* 0x1bd */ + FREG, /* 0x1be */ + FREG, /* 0x1bf */ + FREG, /* 0x1c0 */ + FREG, /* 0x1c1 */ + FREG, /* 0x1c2 */ + FREG, /* 0x1c3 */ + FREG, /* 0x1c4 */ + FREG, /* 0x1c5 */ + FREG, /* 0x1c6 */ + FREG, /* 0x1c7 */ + FREG, /* 0x1c8 */ + FREG, /* 0x1c9 */ + FREG, /* 0x1ca */ + FREG, /* 0x1cb */ + FREG, /* 0x1cc */ + FREG, /* 0x1cd */ + FREG, /* 0x1ce */ + FREG, /* 0x1cf */ + FREG, /* 0x1d0 */ + FREG, /* 0x1d1 */ + FREG, /* 0x1d2 */ + FREG, /* 0x1d3 */ + FREG, /* 0x1d4 */ + FREG, /* 0x1d5 */ + FREG, /* 0x1d6 */ + FREG, /* 0x1d7 */ + FREG, /* 0x1d8 */ + FREG, /* 0x1d9 */ + FREG, /* 0x1da */ + FREG, /* 0x1db */ + FREG, /* 0x1dc */ + FREG, /* 0x1dd */ + FREG, /* 0x1de */ + FREG, /* 0x1df */ + FREG, /* 0x1e0 */ + FREG, /* 0x1e1 */ + FREG, /* 0x1e2 */ + FREG, /* 0x1e3 */ + FREG, /* 0x1e4 */ + FREG, /* 0x1e5 */ + FREG, /* 0x1e6 */ + FREG, /* 0x1e7 */ + FREG, /* 0x1e8 */ + FREG, /* 0x1e9 */ + FREG, /* 0x1ea */ + FREG, /* 0x1eb */ + FREG, /* 0x1ec */ + FREG, /* 0x1ed */ + FREG, /* 0x1ee */ + FREG, /* 0x1ef */ + FREG, /* 0x1f0 */ + FREG, /* 0x1f1 */ + FREG, /* 0x1f2 */ + FREG, /* 0x1f3 */ + FREG, /* 0x1f4 */ + FREG, /* 0x1f5 */ + FREG, /* 0x1f6 */ + FREG, /* 0x1f7 */ + FREG, /* 0x1f8 */ + FREG, /* 0x1f9 */ + FREG, /* 0x1fa */ + FREG, /* 0x1fb */ + FREG, /* 0x1fc */ + FREG, /* 0x1fd */ + FREG, /* 0x1fe */ + FREG, /* 0x1ff */ +}; +// clang-format on + +// memory map for PIC16F883 and PIC16F884 are same +PicMidrangeRegType *pic16f887_reg_map = pic16f886_reg_map; + +#endif // RZ_PIC_MIDRANGE_PIC_MEMMAP_PIC16F886_H diff --git a/librz/arch/isa/pic/pic16f_memmaps/regtypes.h b/librz/arch/isa/pic/pic16f_memmaps/regtypes.h new file mode 100644 index 00000000000..2d699feb597 --- /dev/null +++ b/librz/arch/isa/pic/pic16f_memmaps/regtypes.h @@ -0,0 +1,202 @@ +// SPDX-FileCopyrightText: 2023 Siddharth Mishra +// SPDX-License-Identifier: LGPL-3.0-only + +/** + * Defines the various reigster types supported by the PIC16F family + * and a lookup table to map from these register types to their string names. + * */ + +#ifndef RZ_PIC_MIDRANGE_PIC_REGTYPES_H +#define RZ_PIC_MIDRANGE_PIC_REGTYPES_H + +// clang-format off + +/** + * Instead of storing strings in file register map, + * it's better to store enums in order to save memory. + * */ +typedef enum pic_midrange_reg_type_t { + INDF, + TMR0, + PCL, /* lower byte of PC register */ + STATUS, /* status register */ + FSR, + PORTA, + PORTB, + PORTC, + PORTD, + PORTE, + PORTF, + PORTG, + PCLATH, /* PCLATH is used to control PCH (higher part of PC reg)*/ + INTCON, + PIR1, + PIR2, + TMR1L, + TMR1H, + T1CON, + TMR2, + T2CON, + SSPBUF, + SSPCON, + SSPCON2, + CCPR1L, + CCPR1H, + CCP1CON, + RCSTA, + TXREG, + RCREG, + CCPR2L, + CCPR2H, + CCP2CON, + ADRESH, + ADRESL, + ADCON0, + + ADCON, + OPTION_REG, + TRISA, + TRISB, + TRISC, + TRISD, + TRISE, + TRISF, + TRISG, + PIE1, + PIE2, + PCON, + OSCCON, + OSCCAL, + PR2, + SSPADD, + SSPSTAT, + TXSTA, + SPBRG, + SPBRGH, + ADDCON1, + + OSCTUNE, + WPUB, + IOCB, + VRCON, + PWM1CON, + ECCPAS, + PSTRCON, + ADCON1, + WDTCON, + CM1CON0, + CM2CON0, + CM2CON1, + EEDAT, + EEADR, + EEDATH, + EEADRH, + SRCON, + BAUDCTL, + ANSEL, + ANSELH, + EECON1, + EECON2, + _RESERVED, + FREG, /* normal indexed file register */ + UNIMPLEMENTED, /* unimplemented registers are read as 0 */ + INVALID /* can be used when a function fails and want to return an invalid value */ +} PicMidrangeRegType; + +/** + * Map from reg enums to reg names + * */ +const char* pic_midrange_regnames[] = { + [INDF] = "indf", + [TMR0] = "tmr0", + [PCL] = "pcl", + [STATUS] = "status", + [FSR] = "fsr", + [PORTA] = "porta", + [PORTB] = "portb", + [PORTC] = "portc", + [PORTD] = "portd", + [PORTE] = "porte", + [PORTF] = "portf", + [PORTG] = "portg", + [PCLATH] = "pclath", + [INTCON] = "intcon", + [PIR1] = "pir1", + [PIR2] = "pir2", + [TMR1L] = "tmr1l", + [TMR1H] = "tmr1h", + [T1CON] = "t1con", + [TMR2] = "tmr2", + [T2CON] = "t2con", + [SSPBUF] = "sspbuf", + [SSPCON] = "sspcon", + [SSPCON2] = "sspcon2", + [CCPR1L] = "ccpr1l", + [CCPR1H] = "ccpr1h", + [CCP1CON] = "ccp1con", + [RCSTA] = "rcsta", + [TXREG] = "txreg", + [RCREG] = "rcreg", + [CCPR2L] = "ccpr2l", + [CCPR2H] = "ccpr2h", + [CCP2CON] = "ccp2con", + [ADRESH] = "adresh", + [ADRESL] = "adresl", + [ADCON0] = "adcon0", + [ADCON] = "adcon", + [OPTION_REG] = "option_reg", + [TRISA] = "trisa", + [TRISB] = "trisb", + [TRISC] = "trisc", + [TRISD] = "trisd", + [TRISE] = "trise", + [TRISF] = "trisf", + [TRISG] = "trisg", + [PIE1] = "pie1", + [PIE2] = "pie2", + [PCON] = "pcon", + [OSCCON] = "osccon", + [OSCCAL] = "osccal", + [PR2] = "pr2", + [SSPADD] = "sspadd", + [SSPSTAT] = "sspstat", + [TXSTA] = "txsta", + [SPBRG] = "spbrg", + [SPBRGH] = "spbrgh", + [ADDCON1] = "addcon1", + [OSCTUNE] = "osctune", + [WPUB] = "wpub", + [IOCB] = "iocb", + [VRCON] = "vrcon", + [PWM1CON] = "pwm1con", + [ECCPAS] = "eccpas", + [PSTRCON] = "pstrcon", + [ADCON1] = "adcon1", + [WDTCON] = "wdtcon", + [CM1CON0] = "cm1con0", + [CM2CON0] = "cm2con0", + [CM2CON1] = "cm2con1", + [EEDAT] = "eedat", + [EEADR] = "eeadr", + [EEDATH] = "eedath", + [EEADRH] = "eeadrh", + [SRCON] = "srcon", + [BAUDCTL] = "baudctl", + [ANSEL] = "ansel", + [ANSELH] = "anselh", + [EECON1] = "eecon1", + [EECON2] = "eecon2", + [_RESERVED] = "reserved", + [FREG] = "freg", + [UNIMPLEMENTED] = "unimplemented", +}; +// clang-format on + +static inline const char *pic_midrange_regname(ut32 reg) { + if (reg >= RZ_ARRAY_SIZE(pic_midrange_regnames)) { + return NULL; + } + return pic_midrange_regnames[reg]; +} + +#endif // RZ_PIC_MIDRANGE_PIC_REGTYPES_H diff --git a/librz/arch/isa/pic/pic18_analysis.inc b/librz/arch/isa/pic/pic18_analysis.inc new file mode 100644 index 00000000000..db56473d83e --- /dev/null +++ b/librz/arch/isa/pic/pic18_analysis.inc @@ -0,0 +1,345 @@ +// SPDX-FileCopyrightText: 2015-2018 oddcoder +// SPDX-FileCopyrightText: 2015-2018 thestr4ng3r +// SPDX-FileCopyrightText: 2015-2018 courk +// SPDX-License-Identifier: LGPL-3.0-only + +#include "pic_pic18.h" +#include "pic18_esil.inc" + +static void pic18_cond_branch(RzAnalysisOp *aop, ut64 addr, const ut8 *buf) { + aop->type = RZ_ANALYSIS_OP_TYPE_CJMP; + aop->jump = addr + 2 + 2 * (*(ut16 *)buf & 0xff); + aop->fail = addr + aop->size; + aop->cycles = 2; +} + +static int analysis_pic_pic18_op( + RzAnalysis *analysis, RzAnalysisOp *aop, ut64 addr, + const ut8 *buf, int len, RzAnalysisOpMask mask) { + + aop->size = 2; + Pic18Op op = { 0 }; + if (!pic18_disasm_op(&op, buf, len)) { + goto err; + } + aop->size = op.size; + switch (op.code) { + case PIC18_OPCODE_CALL: + case PIC18_OPCODE_RCALL: + aop->type = RZ_ANALYSIS_OP_TYPE_CALL; + break; + case PIC18_OPCODE_BRA: // bra + aop->type = RZ_ANALYSIS_OP_TYPE_JMP; + aop->cycles = 2; + aop->jump = addr + 2 + 2 * (*(ut16 *)buf & 0x7ff); + break; + case PIC18_OPCODE_MOVFF: // movff + aop->type = RZ_ANALYSIS_OP_TYPE_MOV; + break; + case PIC18_OPCODE_BTFSC: // btfsc + case PIC18_OPCODE_BTFSS: // btfss + aop->type = RZ_ANALYSIS_OP_TYPE_CJMP; + break; + case PIC18_OPCODE_BCF: // bcf + case PIC18_OPCODE_BSF: // bsf + case PIC18_OPCODE_BTG: // btg + aop->type = RZ_ANALYSIS_OP_TYPE_UNK; + break; + case PIC18_OPCODE_BZ: // bz + pic18_cond_branch(aop, addr, buf); + break; + case PIC18_OPCODE_BNZ: // bnz + pic18_cond_branch(aop, addr, buf); + break; + case PIC18_OPCODE_BNC: // bnc + pic18_cond_branch(aop, addr, buf); + break; + case PIC18_OPCODE_BOV: // bov + pic18_cond_branch(aop, addr, buf); + break; + case PIC18_OPCODE_BNOV: // bnov + pic18_cond_branch(aop, addr, buf); + break; + case PIC18_OPCODE_BN: // bn + pic18_cond_branch(aop, addr, buf); + break; + case PIC18_OPCODE_BNN: // bnn + pic18_cond_branch(aop, addr, buf); + break; + case PIC18_OPCODE_BC: // bc + pic18_cond_branch(aop, addr, buf); + break; + case PIC18_OPCODE_GOTO: // goto + aop->cycles = 2; + aop->jump = op.k; + aop->type = RZ_ANALYSIS_OP_TYPE_JMP; + break; + case PIC18_OPCODE_ADDLW: // addlw + aop->type = RZ_ANALYSIS_OP_TYPE_ADD; + aop->cycles = 1; + break; + case PIC18_OPCODE_MOVLW: // movlw + aop->type = RZ_ANALYSIS_OP_TYPE_LOAD; + aop->cycles = 1; + break; + case PIC18_OPCODE_MULLW: // mullw + aop->type = RZ_ANALYSIS_OP_TYPE_MUL; + aop->cycles = 1; + break; + case PIC18_OPCODE_RETLW: // retlw + aop->type = RZ_ANALYSIS_OP_TYPE_RET; + aop->cycles = 2; + break; + case PIC18_OPCODE_ANDLW: // andlw + aop->type = RZ_ANALYSIS_OP_TYPE_AND; + aop->cycles = 1; + break; + case PIC18_OPCODE_XORLW: // xorlw + aop->type = RZ_ANALYSIS_OP_TYPE_XOR; + aop->cycles = 1; + break; + case PIC18_OPCODE_IORLW: // iorlw + aop->type = RZ_ANALYSIS_OP_TYPE_OR; + aop->cycles = 1; + break; + case PIC18_OPCODE_SUBLW: // sublw + aop->type = RZ_ANALYSIS_OP_TYPE_SUB; + aop->cycles = 1; + break; + case PIC18_OPCODE_LFSR: // lfsr + aop->type = RZ_ANALYSIS_OP_TYPE_LOAD; + break; + case PIC18_OPCODE_SUBWF: // subwf + case PIC18_OPCODE_SUBFWB: // subwfb + case PIC18_OPCODE_SUBWFB: // subfwb + case PIC18_OPCODE_DCFSNZ: // dcfsnz + case PIC18_OPCODE_DECFSZ: // decfsz + case PIC18_OPCODE_DECF: // decf + aop->type = RZ_ANALYSIS_OP_TYPE_SUB; + break; + case PIC18_OPCODE_MOVF: // movf + aop->type = RZ_ANALYSIS_OP_TYPE_MOV; + break; + case PIC18_OPCODE_INFSNZ: // infsnz + case PIC18_OPCODE_INCFSZ: // incfsz + case PIC18_OPCODE_INCF: // incf + case PIC18_OPCODE_ADDWFC: // addwfc + aop->type = RZ_ANALYSIS_OP_TYPE_ADD; + break; + case PIC18_OPCODE_ADDWF: // addwf + aop->cycles = 1; + aop->type = RZ_ANALYSIS_OP_TYPE_ADD; + break; + case PIC18_OPCODE_RLNCF: // rlncf + case PIC18_OPCODE_RLCF: // rlcf + aop->type = RZ_ANALYSIS_OP_TYPE_ROL; + break; + case PIC18_OPCODE_RRNCF: // rrncf + case PIC18_OPCODE_RRCF: // rrcf + aop->type = RZ_ANALYSIS_OP_TYPE_ROR; + break; + case PIC18_OPCODE_SWAPF: // swapf + aop->type = RZ_ANALYSIS_OP_TYPE_UNK; + break; + case PIC18_OPCODE_COMF: // comf + aop->type = RZ_ANALYSIS_OP_TYPE_CPL; + break; + case PIC18_OPCODE_XORWF: // xorwf + aop->type = RZ_ANALYSIS_OP_TYPE_XOR; + break; + case PIC18_OPCODE_ANDWF: // andwf + aop->type = RZ_ANALYSIS_OP_TYPE_AND; + break; + case PIC18_OPCODE_IORWF: // iorwf + aop->type = RZ_ANALYSIS_OP_TYPE_OR; + break; + case PIC18_OPCODE_MOVWF: // movwf + aop->type = RZ_ANALYSIS_OP_TYPE_STORE; + break; + case PIC18_OPCODE_NEGF: // negf + case PIC18_OPCODE_CLRF: // clrf + case PIC18_OPCODE_SETF: // setf + aop->type = RZ_ANALYSIS_OP_TYPE_UNK; + break; + case PIC18_OPCODE_TSTFSZ: // tstfsz + aop->type = RZ_ANALYSIS_OP_TYPE_CJMP; + break; + case PIC18_OPCODE_CPFSQT: // cpfsgt + case PIC18_OPCODE_CPFSEQ: // cpfseq + case PIC18_OPCODE_CPFSLT: // cpfslt + aop->type = RZ_ANALYSIS_OP_TYPE_CMP; + break; + case PIC18_OPCODE_MULWF: // mulwf + aop->type = RZ_ANALYSIS_OP_TYPE_MUL; + break; + case PIC18_OPCODE_MOVLB: // movlb + aop->type = RZ_ANALYSIS_OP_TYPE_LOAD; + aop->cycles = 1; + break; + case PIC18_OPCODE_RESET: // reset + case PIC18_OPCODE_DAW: // daw + // case CLWDT // clwdt + case PIC18_OPCODE_SLEEP: // sleep + aop->type = RZ_ANALYSIS_OP_TYPE_UNK; + break; + case PIC18_OPCODE_RETURN: // return + aop->type = RZ_ANALYSIS_OP_TYPE_RET; + aop->cycles = 2; + break; + case PIC18_OPCODE_RETFIE: // retfie + aop->type = RZ_ANALYSIS_OP_TYPE_RET; + break; + case PIC18_OPCODE_TBLWTMm: // tblwt + case PIC18_OPCODE_TBLWTMma: // tblwt + case PIC18_OPCODE_TBLWTam: // tblwt + case PIC18_OPCODE_TBLWTMms: // tblwt + aop->type = RZ_ANALYSIS_OP_TYPE_LOAD; + break; + case PIC18_OPCODE_TBLRDam: // tblrd + case PIC18_OPCODE_TBLRDm: // tblrd + case PIC18_OPCODE_TBLRDma: // tblrd + case PIC18_OPCODE_TBLRDms: // tblrd + aop->type = RZ_ANALYSIS_OP_TYPE_STORE; + break; + case PIC18_OPCODE_POP: // pop + aop->type = RZ_ANALYSIS_OP_TYPE_POP; + break; + case PIC18_OPCODE_PUSH: // push + aop->type = RZ_ANALYSIS_OP_TYPE_PUSH; + break; + case PIC18_OPCODE_NOP: // nop + aop->type = RZ_ANALYSIS_OP_TYPE_NOP; + aop->cycles = 1; + break; + default: + goto err; + } + + if (mask & RZ_ANALYSIS_OP_MASK_ESIL) { + pic18_esil(aop, &op, addr, buf); + } + + return aop->size; +err: + aop->type = RZ_ANALYSIS_OP_TYPE_ILL; + return aop->size; +} + +static char *analysis_pic_pic18_get_reg_profile(RzAnalysis *esil) { + const char *p = + "#pc lives in nowhere actually" + "=PC pc\n" + "=SP tos\n" + "=A0 porta\n" + "=A1 portb\n" + "gpr pc .32 0 0\n" + "gpr pcl .8 0 0\n" + "gpr pclath .8 1 0\n" + "gpr pclatu .8 2 0\n" + "#bsr max is 0b111\n" + "gpr bsr .8 4 0\n" + "#tos doesn't exist\n" + "#general rule of thumb any register of size >8 bits has no existence\n" + "gpr tos .32 5 0\n" + "gpr tosl .8 5 0\n" + "gpr tosh .8 6 0\n" + "gpr tosu .8 7 0\n" + + "gpr indf0 .16 9 0\n" + "gpr fsr0 .12 9 0\n" + "gpr fsr0l .8 9 0\n" + "gpr fsr0h .8 10 0\n" + "gpr indf1 .16 11 0\n" + "gpr fsr1 .12 11 0\n" + "gpr fsr1l .8 11 0\n" + "gpr fsr1h .8 12 0\n" + "gpr indf2 .16 13 0\n" + "gpr fsr2 .12 13 0\n" + "gpr frs2l .8 13 0\n" + "gpr fsr2h .8 14 0\n" + "gpr tblptr .22 15 0\n" + "gpr tblptrl .8 15 0\n" + "gpr tblptrh .8 16 0\n" + "gpr tblptru .8 17 0\n" + "gpr rcon .8 18 0\n" + "gpr memcon .8 19 0\n" + "gpr intcon .8 20 0\n" + "gpr intcon2 .8 21 0\n" + "gpr intcon3 .8 22 0\n" + "gpr pie1 .8 23 0\n" + "gpr porta .7 29 0\n" + "gpr trisa .8 30 0\n" + "gpr portb .8 33 0\n" + "gpr tisb .8 34 0\n" + "gpr latb .8 35 0\n" + "gpr portc .8 36 0\n" + "gpr trisc .8 37 0\n" + "gpr latc .8 38 0\n" + "gpr portd .8 39 0\n" + "gpr trisd .8 40 0\n" + "gpr latd .8 41 0\n" + "gpr pspcon .8 42 0\n" + "gpr porte .8 43 0\n" + "gpr trise .8 44 0\n" + "gpr late .8 45 0\n" + "gpr t0con .8 46 0\n" + "gpr t1con .8 47 0\n" + "gpr t2con .8 48 0\n" + "gpr tmr1h .8 50 0\n" + "gpr tmr0h .8 51 0\n" + "gpr tmr1l .8 52 0\n" + "gpr tmr2 .8 53 0\n" + "gpr pr2 .8 54 0\n" + "gpr ccpr1h .8 55 0\n" + "gpr postinc2 .8 56 0\n" + "gpr ccpr1l .8 57 0\n" + "gpr postdec2 .8 58 0\n" + "gpr ccp1con .8 59 0\n" + "gpr preinc2 .8 60 0\n" + "gpr ccpr2h .8 61 0\n" + "gpr plusw2 .8 62 0\n" + "gpr ccpr2l .8 63 0\n" + "gpr ccp2con .8 64 0\n" + "gpr status .8 65 0\n" + "flg c .1 .520 0\n" + "flg dc .1 .521 0\n" + "flg z .1 .522 0\n" + "flg ov .1 .523 0\n" + "flg n .1 .524 0\n" + "gpr prod .16 66 0\n" + "gpr prodl .8 66 0\n" + "gpr prodh .8 67 0\n" + "gpr osccon .8 68 0\n" + "gpr tmr3h .8 69 0\n" + "gpr lvdcon .8 70 0\n" + "gpr tmr3l .8 71 0\n" + "gpr wdtcon .8 72 0\n" + "gpr t3con .8 73 0\n" + "gpr spbrg .8 74 0\n" + "gpr postinc0 .8 75 0\n" + "gpr rcreg .8 76 0\n" + "gpr postdec0 .8 77 0\n" + "gpr txreg .8 78 0\n" + "gpr preinc0 .8 79 0\n" + "gpr txsta .8 80 0\n" + "gpr plusw0 .8 81 0\n" + "gpr rcsta .8 82 0\n" + "gpr sspbuf .8 83 0\n" + "gpr wreg .8 84 0\n" + "gpr sspadd .8 85 0\n" + "gpr sspstat .8 86 0\n" + "gpr postinc1 .8 87 0\n" + "gpr sspcon1 .8 88 0\n" + "gpr postdec1 .8 89 0\n" + "gpr sspcon2 .8 90 0\n" + "gpr preinc1 .8 91 0\n" + "gpr adresh .8 92 0\n" + "gpr plusw1 .8 93 0\n" + "gpr adresl .8 94 0\n" + "gpr adcon0 .8 95 0\n" + "#stkprt max is 0b11111\n" + "gpr stkptr .8 96 0\n" + "gpr tablat .8 14 0\n"; + + return strdup(p); +} diff --git a/librz/arch/isa/pic/pic18_esil.inc b/librz/arch/isa/pic/pic18_esil.inc new file mode 100644 index 00000000000..63c198f8399 --- /dev/null +++ b/librz/arch/isa/pic/pic18_esil.inc @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: 2015-2018 oddcoder +// SPDX-FileCopyrightText: 2015-2018 thestr4ng3r +// SPDX-FileCopyrightText: 2015-2018 courk +// SPDX-License-Identifier: LGPL-3.0-only + +static void pic18_cond_branch_esil(RzAnalysisOp *aop, ut64 addr, const ut8 *buf, char *flag) { + rz_strbuf_setf(&aop->esil, "%s,?,{,0x%" PFMT64x ",pc,=,}", flag, aop->jump); +} + +static void pic18_esil( + RzAnalysisOp *aop, Pic18Op *op, ut64 addr, const ut8 *buf) { + switch (op->code) { + case PIC18_OPCODE_BRA: // bra + rz_strbuf_setf(&aop->esil, "0x%" PFMT64x ",pc,=", aop->jump); + break; + case PIC18_OPCODE_BZ: // bz + pic18_cond_branch_esil(aop, addr, buf, "z"); + break; + case PIC18_OPCODE_BNZ: // bnz + pic18_cond_branch_esil(aop, addr, buf, "z,!"); + break; + case PIC18_OPCODE_BNC: // bnc + pic18_cond_branch_esil(aop, addr, buf, "c,!"); + break; + case PIC18_OPCODE_BOV: // bov + pic18_cond_branch_esil(aop, addr, buf, "ov"); + break; + case PIC18_OPCODE_BNOV: // bnov + pic18_cond_branch_esil(aop, addr, buf, "ov,!"); + break; + case PIC18_OPCODE_BN: // bn + pic18_cond_branch_esil(aop, addr, buf, "n"); + break; + case PIC18_OPCODE_BNN: // bnn + pic18_cond_branch_esil(aop, addr, buf, "n,!"); + break; + case PIC18_OPCODE_BC: // bc + pic18_cond_branch_esil(aop, addr, buf, "c"); + break; + case PIC18_OPCODE_GOTO: // goto + rz_strbuf_setf(&aop->esil, "0x%" PFMT64x ",pc,=", aop->jump); + break; + case PIC18_OPCODE_ADDLW: // addlw + // TODO add support for dc flag + rz_strbuf_setf(&aop->esil, "0x%x,wreg,+=,$z,z,:=,7,$s,n,:=,7,$c,c,:=,7,$o,ov,:=,", *(ut16 *)buf & 0xff); + break; + case PIC18_OPCODE_MOVLW: // movlw + rz_strbuf_setf(&aop->esil, "0x%x,wreg,=,", *(ut16 *)buf & 0xff); + break; + case PIC18_OPCODE_MULLW: // mullw + rz_strbuf_setf(&aop->esil, "0x%x,wreg,*,prod,=", *(ut16 *)buf & 0xff); + break; + case PIC18_OPCODE_RETLW: // retlw + rz_strbuf_setf(&aop->esil, "0x%x,wreg,=,tos,pc,=,", *(ut16 *)buf & 0xff); + break; + case PIC18_OPCODE_ANDLW: // andlw + rz_strbuf_setf(&aop->esil, "0x%x,wreg,&=,$z,z,:=,7,$s,n,:=,", *(ut16 *)buf & 0xff); + break; + case PIC18_OPCODE_XORLW: // xorlw + rz_strbuf_setf(&aop->esil, "0x%x,wreg,^=,$z,z,:=,7,$s,n,:=,", *(ut16 *)buf & 0xff); + break; + case PIC18_OPCODE_IORLW: // iorlw + rz_strbuf_setf(&aop->esil, "0x%x,wreg,^=,$z,z,:=,7,$s,n,:=,", *(ut16 *)buf & 0xff); + break; + case PIC18_OPCODE_SUBLW: // sublw + // TODO add support for dc flag + rz_strbuf_setf(&aop->esil, "wreg,0x%x,-,wreg,=,$z,z,:=,7,$s,n,:=,7,$c,c,:=,7,$o,ov,:=,", *(ut16 *)buf & 0xff); + break; + case PIC18_OPCODE_MOVLB: // movlb + rz_strbuf_setf(&aop->esil, "0x%x,bsr,=,", *(ut16 *)buf & 0xf); + break; + case PIC18_OPCODE_RETURN: // return + rz_strbuf_setf(&aop->esil, "tos,pc,=,"); + break; + case PIC18_OPCODE_NOP: // nop + rz_strbuf_setf(&aop->esil, ","); + break; + default: break; + } +} \ No newline at end of file diff --git a/librz/arch/isa/pic/pic_il.h b/librz/arch/isa/pic/pic_il.h new file mode 100644 index 00000000000..4bab3a7fc46 --- /dev/null +++ b/librz/arch/isa/pic/pic_il.h @@ -0,0 +1,75 @@ +// SPDX-FileCopyrightText: 2023 Siddharth Mishra +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef PIC_IL_H_ +#define PIC_IL_H_ + +#include +#include + +/** + * PIC Mid-Range Device Type. + * Since each device has it's own set of supported instructions + * and memory map (# of banks, register arrangement etc...), + * we'll support analysis of each of these devices differently! + * */ +typedef enum pic16f_device_type_t { + PIC16F882, + PIC16F883, + PIC16F884, + PIC16F886, + PIC16F887, + PIC_MIDRANGE_SUPPORTED_DEVICE_NUM +} PicMidrangeDeviceType; + +/** + * This struct will store the CPU state of a PIC Mid-Range + * device while being uplifted. + * + * Register are indexed using a value between 0x00-0x7f and a selected bank. + * Instructions are indexed using a page selector (PCLATH) + * Hence we need to maintain a state of CPU while being analyzed. + * + * This opens possibilities of storing more useful data to improve the process. + * */ +typedef struct pic_midrange_cpu_state_t { + PicMidrangeDeviceType device_type; + ut8 selected_bank; ///< for register indexing. + ut8 selected_page; ///< for instruction indexing. + bool skip; +} PicMidrangeCPUState; + +typedef struct _pic_midrange_op_args_val { + ut16 f; + ut16 k; + ut8 d; + ut8 m; + ut8 n; + ut8 b; +} PicMidrangeOpArgsVal; + +typedef struct pic_midrange_il_context_t { + RzAnalysis *analysis; + RzAnalysisOp *op; + PicMidrangeCPUState cpu; + PicMidrangeOpArgsVal args; + ut64 addr; + ut16 d; +} PicMidrangeILContext; + +typedef RzILOpEffect *(*pic_midrange_il_handler)(PicMidrangeILContext *, ut16); + +RZ_IPI bool rz_pic_midrange_cpu_state_setup( + PicMidrangeCPUState *state, + PicMidrangeDeviceType device_type); +RZ_IPI RzAnalysisILConfig *rz_midrange_il_vm_config(RZ_NONNULL RzAnalysis *analysis, PicMidrangeDeviceType device_type); + +// baseline +/* RZ_IPI RzAnalysisILConfig *rz_pic_baseline_il_vm_config(RZ_NONNULL RzAnalysis *analysis); */ +/* RZ_IPI RzILOpEffect *rz_pic_baseline_il_op(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RZ_BORROW RzAnalysisOp *op, ut16 instr ; */ + +// TODO: Add support for PIC18F & other device families + +#include "pic_midrange_il.inc" + +#endif // PIC_IL_H_ diff --git a/librz/arch/isa/pic/pic_midrange_analysis.inc b/librz/arch/isa/pic/pic_midrange_analysis.inc new file mode 100644 index 00000000000..e68ac01a028 --- /dev/null +++ b/librz/arch/isa/pic/pic_midrange_analysis.inc @@ -0,0 +1,259 @@ +// SPDX-FileCopyrightText: 2015-2018 oddcoder +// SPDX-FileCopyrightText: 2015-2018 thestr4ng3r +// SPDX-FileCopyrightText: 2015-2018 courk +// SPDX-License-Identifier: LGPL-3.0-only + +#include "pic_il.h" +#include "pic_midrange.h" + +typedef void (*pic_midrange_inst_handler_t)(RzAnalysis *analysis, RzAnalysisOp *op, + ut64 addr, + PicMidrangeOpArgsVal *args); + +typedef struct { + PicMidrangeOpcode opcode; + PicMidrangeOpArgs args; + pic_midrange_inst_handler_t handler; + pic_midrange_il_handler il_handler; +} PicMidrangeOpAnalysisInfo; + +#define INST_HANDLER(OPCODE_NAME) \ + static void _inst__##OPCODE_NAME(RzAnalysis *analysis, RzAnalysisOp *op, \ + ut64 addr, \ + PicMidrangeOpArgsVal *args) +#define INST_DECL(NAME, ARGS) \ + [PIC_MIDRANGE_OPCODE_##NAME] = { \ + PIC_MIDRANGE_OPCODE_##NAME, PIC_MIDRANGE_OP_ARGS_##ARGS, \ + _inst__##NAME, IL_LIFTER(NAME) \ + } + +#include "pic_midrange_esil.inc" + +static const PicMidrangeOpAnalysisInfo pic_midrange_op_analysis_info[] = { + INST_DECL(NOP, NONE), + INST_DECL(RETURN, NONE), + INST_DECL(RETFIE, NONE), + INST_DECL(OPTION, NONE), + INST_DECL(SLEEP, NONE), + INST_DECL(CLRWDT, NONE), + INST_DECL(TRIS, 2F), + INST_DECL(MOVWF, 7F), + INST_DECL(CLR, 1D_7F), + INST_DECL(SUBWF, 1D_7F), + INST_DECL(DECF, 1D_7F), + INST_DECL(IORWF, 1D_7F), + INST_DECL(ANDWF, 1D_7F), + INST_DECL(XORWF, 1D_7F), + INST_DECL(ADDWF, 1D_7F), + INST_DECL(MOVF, 1D_7F), + INST_DECL(COMF, 1D_7F), + INST_DECL(INCF, 1D_7F), + INST_DECL(DECFSZ, 1D_7F), + INST_DECL(RRF, 1D_7F), + INST_DECL(RLF, 1D_7F), + INST_DECL(SWAPF, 1D_7F), + INST_DECL(INCFSZ, 1D_7F), + INST_DECL(BCF, 3B_7F), + INST_DECL(BSF, 3B_7F), + INST_DECL(BTFSC, 3B_7F), + INST_DECL(BTFSS, 3B_7F), + INST_DECL(CALL, 11K), + INST_DECL(GOTO, 11K), + INST_DECL(MOVLW, 8K), + INST_DECL(RETLW, 8K), + INST_DECL(IORLW, 8K), + INST_DECL(ANDLW, 8K), + INST_DECL(XORLW, 8K), + INST_DECL(SUBLW, 8K), + INST_DECL(ADDLW, 8K), + INST_DECL(RESET, NONE), + INST_DECL(CALLW, NONE), + INST_DECL(BRW, NONE), + INST_DECL(MOVIW_1, 1N_2M), + INST_DECL(MOVWI_1, 1N_2M), + INST_DECL(MOVLB, 4K), + INST_DECL(LSLF, 1D_7F), + INST_DECL(LSRF, 1D_7F), + INST_DECL(ASRF, 1D_7F), + INST_DECL(SUBWFB, 1D_7F), + INST_DECL(ADDWFC, 1D_7F), + INST_DECL(ADDFSR, 1N_6K), + INST_DECL(MOVLP, 7F), + INST_DECL(BRA, 9K), + INST_DECL(MOVIW_2, 1N_6K), + INST_DECL(MOVWI_2, 1N_6K), + INST_DECL(CLRF, 7F), +}; + +static void analysis_pic_midrange_extract_args( + ut16 instr, + PicMidrangeOpArgs args, + PicMidrangeOpArgsVal *args_val) { + + memset(args_val, 0, sizeof(PicMidrangeOpArgsVal)); + + switch (args) { + case PIC_MIDRANGE_OP_ARGS_NONE: return; + case PIC_MIDRANGE_OP_ARGS_2F: + args_val->f = instr & PIC_MIDRANGE_OP_ARGS_2F_MASK_F; + return; + case PIC_MIDRANGE_OP_ARGS_7F: + args_val->f = instr & PIC_MIDRANGE_OP_ARGS_7F_MASK_F; + return; + case PIC_MIDRANGE_OP_ARGS_1D_7F: + args_val->f = instr & PIC_MIDRANGE_OP_ARGS_1D_7F_MASK_F; + args_val->d = + (instr & PIC_MIDRANGE_OP_ARGS_1D_7F_MASK_D) >> 7; + return; + case PIC_MIDRANGE_OP_ARGS_1N_6K: + args_val->n = + (instr & PIC_MIDRANGE_OP_ARGS_1N_6K_MASK_N) >> 6; + args_val->k = instr & PIC_MIDRANGE_OP_ARGS_1N_6K_MASK_K; + return; + case PIC_MIDRANGE_OP_ARGS_3B_7F: + args_val->b = + (instr & PIC_MIDRANGE_OP_ARGS_3B_7F_MASK_B) >> 7; + args_val->f = instr & PIC_MIDRANGE_OP_ARGS_3B_7F_MASK_F; + return; + case PIC_MIDRANGE_OP_ARGS_4K: + args_val->k = instr & PIC_MIDRANGE_OP_ARGS_4K_MASK_K; + return; + case PIC_MIDRANGE_OP_ARGS_8K: + args_val->k = instr & PIC_MIDRANGE_OP_ARGS_8K_MASK_K; + return; + case PIC_MIDRANGE_OP_ARGS_9K: + args_val->k = instr & PIC_MIDRANGE_OP_ARGS_9K_MASK_K; + return; + case PIC_MIDRANGE_OP_ARGS_11K: + args_val->k = instr & PIC_MIDRANGE_OP_ARGS_11K_MASK_K; + return; + case PIC_MIDRANGE_OP_ARGS_1N_2M: + args_val->n = + (instr & PIC_MIDRANGE_OP_ARGS_1N_2M_MASK_N) >> 2; + args_val->m = instr & PIC_MIDRANGE_OP_ARGS_1N_2M_MASK_M; + return; + } +} + +static RzIODesc *cpu_memory_map( + RzIOBind *iob, RzIODesc *desc, ut32 addr, ut32 size) { + char mstr[16]; + rz_strf(mstr, "malloc://%d", size); + if (desc && iob->fd_get_name(iob->io, desc->fd)) { + iob->fd_remap(iob->io, desc->fd, addr); + } else { + desc = iob->open_at(iob->io, mstr, RZ_PERM_RW, 0, addr, NULL); + } + return desc; +} + +static bool pic_midrange_reg_write(RzReg *reg, const char *regname, ut32 num) { + if (reg) { + RzRegItem *item = rz_reg_get(reg, regname, RZ_REG_TYPE_GPR); + if (item) { + rz_reg_set_value(reg, item, num); + return true; + } + } + return false; +} + +static void analysis_pic_midrange_setup(RzAnalysis *analysis, bool force) { + PicContext *ctx = (PicContext *)analysis->plugin_data; + + if (!ctx->init_done || force) { + // Allocate memory as needed. + // We assume that code is already allocated with firmware + // image + ctx->mem_sram = + cpu_memory_map(&analysis->iob, ctx->mem_sram, + PIC_MIDRANGE_ESIL_SRAM_START, 0x1000); + ctx->mem_stack = + cpu_memory_map(&analysis->iob, ctx->mem_sram, + PIC_MIDRANGE_ESIL_CSTACK_TOP, 0x20); + + pic_midrange_reg_write(analysis->reg, "_sram", + PIC_MIDRANGE_ESIL_SRAM_START); + pic_midrange_reg_write(analysis->reg, "_stack", + PIC_MIDRANGE_ESIL_CSTACK_TOP); + pic_midrange_reg_write(analysis->reg, "stkptr", 0x1f); + + ctx->init_done = true; + } +} + +static int analysis_pic_midrange_op( + RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, + const ut8 *buf, int len, RzAnalysisOpMask mask) { + + if (!buf || len < 2) { + op->type = RZ_ANALYSIS_OP_TYPE_ILL; + return op->size; + } + + analysis_pic_midrange_setup(analysis, false); + ut16 instr = rz_read_le16(buf); + // Default op params + op->size = 2; + op->cycles = 1; + op->type = RZ_ANALYSIS_OP_TYPE_NOP; + + PicMidrangeOpcode opcode = pic_midrange_get_opcode(instr); + PicMidrangeOpArgsVal args_val; + + if (opcode < RZ_ARRAY_SIZE(pic_midrange_op_analysis_info)) { + const PicMidrangeOpAnalysisInfo *info = pic_midrange_op_analysis_info + opcode; + if (!info) { + return -1; + } + analysis_pic_midrange_extract_args( + instr, info->args, + &args_val); + if (mask & RZ_ANALYSIS_OP_MASK_ESIL) { + info->handler(analysis, op, addr, &args_val); + } + if (mask & RZ_ANALYSIS_OP_MASK_IL) { + PicMidrangeILContext il_ctx = { + .analysis = analysis, + .op = op, + .args = args_val, + .addr = addr, + .d = instr, + }; + rz_pic_midrange_cpu_state_setup(&il_ctx.cpu, PIC16F886); + op->il_op = info->il_handler(&il_ctx, opcode); + } + } + + return op->size; +} + +static char *analysis_pic_midrange_get_reg_profile(RzAnalysis *a) { + const char *p = + "=PC pc\n" + "=SP stkptr\n" + "=A0 porta\n" + "=A1 portb\n" + "gpr indf0 .8 0 0\n" + "gpr indf1 .8 1 0\n" + "gpr pcl .8 2 0\n" + "gpr status .8 3 0\n" + "flg c .1 3.0 0\n" + "flg dc .1 3.1 0\n" + "flg z .1 3.2 0\n" + "flg pd .1 3.3 0\n" + "flg to .1 3.4 0\n" + "gpr fsr0l .8 4 0\n" + "gpr fsr0h .8 5 0\n" + "gpr fsr1l .8 6 0\n" + "gpr fsr1h .8 7 0\n" + "gpr bsr .8 8 0\n" + "gpr wreg .8 9 0\n" + "gpr pclath .8 10 0\n" + "gpr intcon .8 11 0\n" + "gpr pc .16 12 0\n" + "gpr stkptr .8 14 0\n" + "gpr _sram .32 15 0\n" + "gpr _stack .32 19 0\n"; + return strdup(p); +} diff --git a/librz/arch/isa/pic/pic_midrange_esil.inc b/librz/arch/isa/pic/pic_midrange_esil.inc new file mode 100644 index 00000000000..eefffc4a178 --- /dev/null +++ b/librz/arch/isa/pic/pic_midrange_esil.inc @@ -0,0 +1,522 @@ +// SPDX-FileCopyrightText: 2015-2018 oddcoder +// SPDX-FileCopyrightText: 2015-2018 thestr4ng3r +// SPDX-FileCopyrightText: 2015-2018 courk +// SPDX-License-Identifier: LGPL-3.0-only + +#define e(frag) rz_strbuf_append(&op->esil, frag) +#define ef(frag, ...) rz_strbuf_appendf(&op->esil, frag, __VA_ARGS__) + +#define PIC_MIDRANGE_ESIL_SRAM_START (1 << 16) +#define PIC_MIDRANGE_ESIL_CSTACK_TOP ((1 << 16) + (1 << 12)) + +#define PIC_MIDRANGE_ESIL_BSR_ADDR "bsr,0x80,*,0x%x,+,_sram,+" + +#define PIC_MIDRANGE_ESIL_OPTION_ADDR "0x95,_sram,+" + +#define PIC_MIDRANGE_ESIL_UPDATE_FLAGS \ + "$z,z,:=," \ + "7,$c,c,:=," \ + "4,$c,dc,:=," + +#define PIC_MIDRANGE_ESIL_LW_OP(O) \ + "0x%x,wreg," #O "=," PIC_MIDRANGE_ESIL_UPDATE_FLAGS + +#define PIC_MIDRANGE_ESIL_FWF_OP(O) \ + "wreg," PIC_MIDRANGE_ESIL_BSR_ADDR "," #O \ + "=[1]," PIC_MIDRANGE_ESIL_UPDATE_FLAGS + +#define PIC_MIDRANGE_ESIL_WWF_OP(O) \ + PIC_MIDRANGE_ESIL_BSR_ADDR \ + ",[1]," \ + "wreg," #O "=," PIC_MIDRANGE_ESIL_UPDATE_FLAGS + +#define PIC_MIDRANGE_ESIL_FWF_OP_C(O) \ + "c,wreg," \ + "+," PIC_MIDRANGE_ESIL_BSR_ADDR "," #O \ + "=[1]," PIC_MIDRANGE_ESIL_UPDATE_FLAGS + +#define PIC_MIDRANGE_ESIL_WWF_OP_C(O) \ + "c," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1]," #O "," \ + "wreg," #O "=," PIC_MIDRANGE_ESIL_UPDATE_FLAGS + +INST_HANDLER(NOP) {} + +INST_HANDLER(RETFIE) { + op->type = RZ_ANALYSIS_OP_TYPE_RET; +} + +INST_HANDLER(OPTION) { + op->type = RZ_ANALYSIS_OP_TYPE_STORE; +} + +INST_HANDLER(TRIS) { + op->type = RZ_ANALYSIS_OP_TYPE_STORE; +} + +INST_HANDLER(RETURN) { + op->type = RZ_ANALYSIS_OP_TYPE_RET; + e("0x1f,stkptr,==,$z,?{,BREAK,},"); + e("_stack,stkptr,2,*,+,[2],2,*,pc,=,"); + e("0x01,stkptr,-=,"); + e("0xff,stkptr,==,$z,?{,0x1f,stkptr,=,},"); +} + +INST_HANDLER(CALL) { + ut64 pclath; + op->type = RZ_ANALYSIS_OP_TYPE_CALL; + rz_analysis_esil_reg_read(analysis->esil, "pclath", &pclath, NULL); + op->jump = 2 * (((pclath & 0x78) << 8) + args->k); + ef("8,pclath,0x78,&,<<,0x%x,+,2,*,pc,=,", args->k); + e("0x1f,stkptr,==,$z,?{,0xff,stkptr,=,},"); + e("0x0f,stkptr,==,$z,?{,0xff,stkptr,=,},"); + e("0x01,stkptr,+=,"); + ef("0x%" PFMT64x ",_stack,stkptr,2,*,+,=[2],", (addr + 2) / 2); +} + +INST_HANDLER(GOTO) { + ut64 pclath; + op->type = RZ_ANALYSIS_OP_TYPE_JMP; + rz_analysis_esil_reg_read(analysis->esil, "pclath", &pclath, NULL); + op->jump = 2 * (((pclath & 0x78) << 8) + args->k); + ef("8,pclath,0x78,&,<<,0x%x,+,2,*,pc,=,", args->k); +} + +INST_HANDLER(BCF) { + ut8 mask = ~(1 << args->b); + ef(PIC_MIDRANGE_ESIL_BSR_ADDR + ",[1],0x%x,&," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", + args->f, mask, args->f); +} + +INST_HANDLER(BSF) { + ut8 mask = (1 << args->b); + ef(PIC_MIDRANGE_ESIL_BSR_ADDR + ",[1],0x%x,|," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", + args->f, mask, args->f); +} + +INST_HANDLER(BTFSC) { + ut8 mask = (1 << args->b); + op->type = RZ_ANALYSIS_OP_TYPE_CJMP; + op->jump = addr + 4; + op->fail = addr + 2; + ef(PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],0x%x,&,!,?{,0x%" PFMT64x ",pc,=,},", + args->f, mask, op->jump); +} + +INST_HANDLER(BTFSS) { + ut8 mask = (1 << args->b); + op->type = RZ_ANALYSIS_OP_TYPE_CJMP; + op->jump = addr + 4; + op->fail = addr + 2; + ef(PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],0x%x,&,?{,0x%" PFMT64x ",pc,=,},", args->f, + mask, op->jump); +} + +INST_HANDLER(BRA) { + st16 branch = args->k; + op->type = RZ_ANALYSIS_OP_TYPE_JMP; + branch |= ((branch & 0x100) ? 0xfe00 : 0); + op->jump = addr + 2 * (branch + 1); + ef("%s0x%x,1,+,2,*,pc,+=,", branch < 0 ? "-" : "", + branch < 0 ? -branch : branch); +} + +INST_HANDLER(BRW) { + ut64 wreg; + op->type = RZ_ANALYSIS_OP_TYPE_UJMP; + rz_analysis_esil_reg_read(analysis->esil, "wreg", &wreg, NULL); + op->jump = addr + 2 * (wreg + 1); + e("wreg,1,+,2,*,pc,+=,"); +} + +INST_HANDLER(CLR) { + if (args->d) { + ef("0x00," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", args->f); + } else { + e("0x00,wreg,=,"); + } + e("1,z,=,"); +} + +INST_HANDLER(SUBWF) { + op->type = RZ_ANALYSIS_OP_TYPE_SUB; + if (args->d) { + ef(PIC_MIDRANGE_ESIL_FWF_OP(-), args->f); + } else { + ef(PIC_MIDRANGE_ESIL_WWF_OP(-), args->f); + e("wreg,0x00,-,wreg,=,c,!=,dc,!=,"); + } +} + +INST_HANDLER(DECFSZ) { + op->type = RZ_ANALYSIS_OP_TYPE_CJMP; + op->jump = addr + 4; + op->fail = addr + 2; + if (args->d) { + ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",-=[1],", args->f); + } else { + ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],-,wreg,=,", + args->f); + } + ef(PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],!,?{,0x%" PFMT64x ",pc,=,},", args->f, + op->jump); +} + +INST_HANDLER(INCFSZ) { + op->type = RZ_ANALYSIS_OP_TYPE_CJMP; + op->jump = addr + 4; + op->fail = addr + 2; + if (args->d) { + ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",+=[1],", args->f); + } else { + ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],+,wreg,=,", + args->f); + } + ef(PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],!,?{,0x%" PFMT64x ",pc,=,},", args->f, + op->jump); +} + +INST_HANDLER(INCF) { + op->type = RZ_ANALYSIS_OP_TYPE_ADD; + if (args->d) { + ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",+=[1],", args->f); + } else { + ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],+,wreg,=,", + args->f); + } + e("$z,z,:=,"); +} + +INST_HANDLER(DECF) { + op->type = RZ_ANALYSIS_OP_TYPE_SUB; + if (args->d) { + ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",-=[1],", args->f); + } else { + ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],-,wreg,=,", + args->f); + } + e("$z,z,:=,"); +} + +INST_HANDLER(IORWF) { + op->type = RZ_ANALYSIS_OP_TYPE_OR; + if (args->d) { + ef(PIC_MIDRANGE_ESIL_FWF_OP(|), args->f); + } else { + ef(PIC_MIDRANGE_ESIL_WWF_OP(|), args->f); + } +} + +INST_HANDLER(ANDWF) { + op->type = RZ_ANALYSIS_OP_TYPE_AND; + if (args->d) { + ef(PIC_MIDRANGE_ESIL_FWF_OP(&), args->f); + } else { + ef(PIC_MIDRANGE_ESIL_WWF_OP(&), args->f); + } +} + +INST_HANDLER(XORWF) { + op->type = RZ_ANALYSIS_OP_TYPE_XOR; + if (args->d) { + ef(PIC_MIDRANGE_ESIL_FWF_OP(^), args->f); + } else { + ef(PIC_MIDRANGE_ESIL_WWF_OP(^), args->f); + } +} + +INST_HANDLER(ADDWF) { + op->type = RZ_ANALYSIS_OP_TYPE_ADD; + if (args->d) { + ef(PIC_MIDRANGE_ESIL_FWF_OP(+), args->f); + } else { + ef(PIC_MIDRANGE_ESIL_WWF_OP(+), args->f); + } +} + +INST_HANDLER(SUBLW) { + op->type = RZ_ANALYSIS_OP_TYPE_SUB; + ef(PIC_MIDRANGE_ESIL_LW_OP(-), args->k); +} + +INST_HANDLER(ADDLW) { + op->type = RZ_ANALYSIS_OP_TYPE_ADD; + ef(PIC_MIDRANGE_ESIL_LW_OP(+), args->k); +} + +INST_HANDLER(IORLW) { + op->type = RZ_ANALYSIS_OP_TYPE_OR; + ef(PIC_MIDRANGE_ESIL_LW_OP(|), args->k); +} + +INST_HANDLER(ANDLW) { + op->type = RZ_ANALYSIS_OP_TYPE_AND; + ef(PIC_MIDRANGE_ESIL_LW_OP(&), args->k); +} + +INST_HANDLER(XORLW) { + op->type = RZ_ANALYSIS_OP_TYPE_XOR; + ef(PIC_MIDRANGE_ESIL_LW_OP(^), args->k); +} + +INST_HANDLER(MOVLW) { + op->type = RZ_ANALYSIS_OP_TYPE_LOAD; + ef("0x%x,wreg,=,", args->k); +} + +INST_HANDLER(RETLW) { + op->type = RZ_ANALYSIS_OP_TYPE_RET; + ef("0x%x,wreg,=,", args->k); + e("0x1f,stkptr,==,$z,?{,BREAK,},"); + e("_stack,stkptr,2,*,+,[2],2,*,pc,=,"); + e("0x01,stkptr,-=,"); + e("0xff,stkptr,==,$z,?{,0x1f,stkptr,=,},"); +} + +INST_HANDLER(MOVLP) { + op->type = RZ_ANALYSIS_OP_TYPE_LOAD; + ef("0x%x,pclath,=,", args->f); +} + +INST_HANDLER(MOVLB) { + op->type = RZ_ANALYSIS_OP_TYPE_LOAD; + ef("0x%x,bsr,=,", args->k); +} + +INST_HANDLER(CALLW) { + op->type = RZ_ANALYSIS_OP_TYPE_UCALL; + e("8,pclath,<<,0x%x,+,wreg,2,*,pc,=,"); + e("0x1f,stkptr,==,$z,?{,0xff,stkptr,=,},"); + e("0x0f,stkptr,==,$z,?{,0xff,stkptr,=,},"); + e("0x01,stkptr,+=,"); + ef("0x%" PFMT64x ",_stack,stkptr,2,*,+,=[2],", (addr + 2) / 2); +} + +INST_HANDLER(MOVWF) { + op->type = RZ_ANALYSIS_OP_TYPE_STORE; + ef("wreg," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", args->f); +} + +INST_HANDLER(MOVF) { + op->type = RZ_ANALYSIS_OP_TYPE_LOAD; + if (args->d) { + ef(PIC_MIDRANGE_ESIL_BSR_ADDR + ",[1]," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", + args->f, args->f); + } else { + ef(PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],wreg,=,", args->f); + } + e("$z,z,:=,"); +} + +INST_HANDLER(SWAPF) { + ef("4," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,0x0f,&,", args->f); + ef("4," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],<<,0xf0,&,", args->f); + e("|,"); + ef(PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", args->f); +} + +INST_HANDLER(LSLF) { + op->type = RZ_ANALYSIS_OP_TYPE_SHL; + ef("7," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,c,=,", args->f); + if (args->d) { + ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",<<=[1],", args->f); + } else { + ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],<<,wreg,=,", + args->f); + } + e("$z,z,:=,"); +} + +INST_HANDLER(LSRF) { + op->type = RZ_ANALYSIS_OP_TYPE_SHR; + ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],&,c,=,", args->f); + if (args->d) { + ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",>>=[1],", args->f); + } else { + ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,wreg,=,", + args->f); + } + e("$z,z,:=,"); +} + +INST_HANDLER(ASRF) { + op->type = RZ_ANALYSIS_OP_TYPE_SHR; + ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],&,c,=,", args->f); + ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,", args->f); + ef("0x80," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],&,", args->f); + if (args->d) { + ef("|," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", args->f); + } else { + e("|,wreg,=,"); + } + e("$z,z,:=,"); +} + +INST_HANDLER(RRF) { + op->type = RZ_ANALYSIS_OP_TYPE_ROR; + ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],&,", args->f); + if (args->d) { + ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",>>=[1]," + "c," PIC_MIDRANGE_ESIL_BSR_ADDR ",|=[1],", + args->f, args->f); + } else { + ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,wreg,=," + "c,wreg,|=[1],", + args->f); + } + e("c,=,"); +} + +INST_HANDLER(RLF) { + op->type = RZ_ANALYSIS_OP_TYPE_ROL; + ef("7," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,", args->f); + if (args->d) { + ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",<<=[1]," + "c," PIC_MIDRANGE_ESIL_BSR_ADDR ",|=[1],", + args->f, args->f); + } else { + ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],<<,wreg,=," + "c,wreg,|=[1],", + args->f); + } + e("c,=,"); +} + +INST_HANDLER(COMF) { + if (args->d) { + ef("0xff," PIC_MIDRANGE_ESIL_BSR_ADDR ",^=[1],", args->f); + } else { + ef("0xff," PIC_MIDRANGE_ESIL_BSR_ADDR ",^,wreg,=,", args->f); + } + e("$z,z,:=,"); +} + +INST_HANDLER(RESET) { + op->type = RZ_ANALYSIS_OP_TYPE_JMP; + op->jump = 0; + e("0x0,pc,=,"); + e("0x1f,stkptr,=,"); +} + +INST_HANDLER(ADDFSR) { + op->type = RZ_ANALYSIS_OP_TYPE_ADD; + if (args->n == 0) { + ef("0x%x,fsr0l,+=,", args->k); + e("7,$c,?{,0x01,fsr0h,+=,},"); + } else { + ef("0x%x,fsr1l,+=,", args->k); + e("7,$c,?{,0x01,fsr1h,+=,},"); + } +} + +INST_HANDLER(CLRWDT) { + e("1,to,=,"); + e("1,pd,=,"); +} + +INST_HANDLER(SLEEP) { + e("1,to,=,"); + e("0,pd,=,"); +} + +INST_HANDLER(SUBWFB) { + op->type = RZ_ANALYSIS_OP_TYPE_SUB; + e("c,!=,"); + if (args->d) { + ef(PIC_MIDRANGE_ESIL_FWF_OP_C(-), args->f); + } else { + ef(PIC_MIDRANGE_ESIL_WWF_OP_C(-), args->f); + e("wreg,0x00,-,wreg,=,c,!=,dc,!=,"); + } +} + +INST_HANDLER(ADDWFC) { + op->type = RZ_ANALYSIS_OP_TYPE_ADD; + if (args->d) { + ef(PIC_MIDRANGE_ESIL_FWF_OP_C(+), args->f); + } else { + ef(PIC_MIDRANGE_ESIL_WWF_OP_C(+), args->f); + } +} + +INST_HANDLER(MOVIW_1) { + if (args->n == 0) { + if (!(args->m & 2)) { + ef("1,fsr0l,%s=,", (args->m & 1) ? "-" : "+"); + ef("7,$c%s,fsr0h,%s,", (args->m & 1) ? ",!" : "", + (args->m & 1) ? "-" : "+"); + } + e("indf0,wreg,=,"); + e("$z,z,:=,"); + if (args->m & 2) { + ef("1,fsr0l,%s=,", (args->m & 1) ? "-" : "+"); + ef("7,$c%s,fsr0h,%s,", (args->m & 1) ? ",!" : "", + (args->m & 1) ? "-" : "+"); + } + } else { + if (!(args->m & 2)) { + ef("1,fsr1l,%s=,", (args->m & 1) ? "-" : "+"); + ef("7,$c%s,fsr1h,%s,", (args->m & 1) ? ",!" : "", + (args->m & 1) ? "-" : "+"); + } + e("indf1,wreg,=,"); + e("$z,z,:=,"); + if (args->m & 2) { + ef("1,fsr1l,%s=,", (args->m & 1) ? "-" : "+"); + ef("7,$c%s,fsr1h,%s,", (args->m & 1) ? ",!" : "", + (args->m & 1) ? "-" : "+"); + } + } +} + +INST_HANDLER(MOVWI_1) { + if (args->n == 0) { + if (!(args->m & 2)) { + ef("1,fsr0l,%s=,", (args->m & 1) ? "-" : "+"); + ef("$c7%s,fsr0h,%s,", (args->m & 1) ? ",!" : "", + (args->m & 1) ? "-" : "+"); + } + e("wreg,indf0=,"); + e("$z,z,:=,"); + if (args->m & 2) { + ef("1,fsr0l,%s=,", (args->m & 1) ? "-" : "+"); + ef("$c7%s,fsr0h,%s,", (args->m & 1) ? ",!" : "", + (args->m & 1) ? "-" : "+"); + } + } else { + if (!(args->m & 2)) { + ef("1,fsr1l,%s=,", (args->m & 1) ? "-" : "+"); + ef("$c7,fsr1h,%s,", (args->m & 1) ? ",!" : ""); + } + e("wreg,indf1=,"); + e("$z,z,:=,"); + if (args->m & 2) { + ef("1,fsr1l,%s=,", (args->m & 1) ? "-" : "+"); + ef("$c7%s,fsr1h,%s,", (args->m & 1) ? ",!" : "", + (args->m & 1) ? "-" : "+"); + } + } +} + +INST_HANDLER(MOVIW_2) { + if (args->n == 0) { + e("fsr0l,8,fsr0h,<<,+,"); + } else { + e("fsr1l,8,fsr1h,<<,+,"); + } + ef("0x%x,+,[1],wreg,=,", args->k); +} + +INST_HANDLER(MOVWI_2) { + e("wreg,"); + if (args->n == 0) { + e("fsr0l,8,fsr0h,<<,+,"); + } else { + e("fsr1l,8,fsr1h,<<,+,"); + } + e("=[1],"); +} + +INST_HANDLER(CLRF) {} diff --git a/librz/arch/isa/pic/pic_midrange_il.inc b/librz/arch/isa/pic/pic_midrange_il.inc new file mode 100644 index 00000000000..c0a855b126f --- /dev/null +++ b/librz/arch/isa/pic/pic_midrange_il.inc @@ -0,0 +1,514 @@ +// SPDX-FileCopyrightText: 2023 Siddharth Mishra +// SPDX-FileCopyrightText: 2024 Billow +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include + +#include "pic_il.h" +#include "pic_midrange.h" + +#include + +// HELPER DEFINES & TYPEDEFS + +#define IL_LIFTER(op) pic_midrange_##op##_il_lifter +#define IL_LIFTER_IMPL(op) static RzILOpEffect *pic_midrange_##op##_il_lifter( \ + RZ_NONNULL PicMidrangeILContext *ctx, ut16 instr) + +// REGISTER DECLARATIONS & DEFINITIONS +#include "pic16f_memmaps/memmaps.h" + +#define BANK_SIZE ((ut32)0x80) +#define BANK_COMMON_MAP_LOW cpu_state->selected_bank *BANK_SIZE + 0X70 +#define BANK_COMMON_MAP_HIGH cpu_state->selected_bank *BANK_SIZE + 0X7F + +#define K (ctx->args.k) +#define D (ctx->args.d) +#define F (ctx->args.f) +#define B (ctx->args.b) +#define N (ctx->args.n) +#define PC (ctx->addr) +#define RW "w" +#define RF pic_midrange_regname(F) +#define RWF (D ? pic_midrange_regname(F) : "w") +#define VRF (VARG(pic_midrange_regname(F))) +#define VRW (VARG(RW)) +#define VRWF (VARG(RWF)) +#define VPC (U16(PC)) + +#define INS_LEN 2 + +// device to register schema map +PicMidrangeRegType *pic_midrange_device_reg_map[] = { + [PIC16F882] = pic16f882_reg_map, + [PIC16F883] = pic16f883_reg_map, + // [PIC16F884] = pic16f884_reg_map, + [PIC16F886] = pic16f886_reg_map, + // [PIC16F887] = pic16f887_reg_map, +}; + +static RzILOpPure *SLICE(RzILOpPure *x, ut8 l, ut8 r) { + return LOGAND(SHIFTR0(x, U16(l)), U16(~(-1 << (r - l + 1)))); +} + +#define SEXT(B, x, b) ((st##B)(x << (B - b)) >> (B - b)) + +static const char *RFSR(ut8 n) { + static const char *FSR_names[] = { + "FSR0", "FSR1" + }; + if (n >= RZ_ARRAY_SIZE(FSR_names)) { + return NULL; + } + return FSR_names[n]; +} + +#define VRFSR(n) VARG(RFSR(n)) + +#define BITN(x, n) IS_ZERO(LOGAND(SHIFTR0(x, U32(n)), U32(1))) +// overflow is not used in status register but just keeping this for future "maybe" use +#define CHECK_OVERFLOW(x, y, res) AND(XOR(MSB(x), MSB(res)), XOR(MSB(y), MSB(res))) +#define CHECK_CARRY(x, y, res) OR(AND(MSB(x), MSB(y)), AND(OR(MSB(x), MSB(y)), INV(MSB(res)))) +#define CHECK_BORROW(x, y, res) OR(OR(AND(INV(MSB(x)), MSB(y)), AND(INV(MSB(x)), MSB(res))), AND(MSB(x), AND(MSB(y), MSB(res)))) +#define CHECK_DIGIT_CARRY(x, y, res) OR(AND(BITN(x, 3), BITN(y, 3)), AND(OR(BITN(x, 3), BITN(y, 3)), INV(BITN(res, 3)))) +#define CHECK_DIGIT_BORROW(x, y, res) OR( \ + OR(AND(INV(BITN(x, 3)), BITN(y, 3)), AND(INV(BITN(x, 3)), BITN(res, 3))), \ + AND(BITN(x, 3), AND(BITN(y, 3), BITN(res, 3)))) + +/** + * Handle C, DC & Z flags for the previous operation. + * To be used after an arithmetic operation. + * Order of operands must be preserved for subtraction + * operations, i.e `add = false` + * + * \param x First operand + * \param y Second operand + * \param res Result of last performed operation that affected the flag. + * \param add Was this an add operation? + * + * \return \c RzILOpEffect containing set of steps to set status flags. + * */ +RzILOpEffect *pic_midrange_il_set_arithmetic_flags( + RZ_BORROW RzILOpPure *x, RZ_BORROW RzILOpPure *y, RZ_BORROW RzILOpPure *res, bool add) { + // get carry flag + RzILOpBool *cf = NULL; + RzILOpBool *dcf = NULL; + if (add) { + cf = CHECK_CARRY(x, y, res); + dcf = CHECK_DIGIT_CARRY(x, y, res); + } else { // sub + cf = CHECK_BORROW(x, y, res); + dcf = CHECK_DIGIT_BORROW(x, y, res); + } + + // get zero flag + RzILOpBool *zf = IS_ZERO(res); + + return SEQ3(SETG("c", cf), + SETG("dc", dcf), + SETG("z", zf)); +} + +#define SET_STATUS_ADD(x, y, r) pic_midrange_il_set_arithmetic_flags(x, y, r, true) +#define SET_STATUS_SUB(x, y, r) pic_midrange_il_set_arithmetic_flags(x, y, r, false) + +/** + * NOP + * Operation: No Operation. + * Operands: NONE + * Status affected : NONE + * */ +IL_LIFTER_IMPL(NOP) { + return NOP(); +} + +/** + * ADDLW. + * Operation: Add Literal To wreg + * Operands: Literal (k) + * Status affected : C, DC, Z + * */ +IL_LIFTER_IMPL(ADDLW) { + RzILOpEffect *add_op = SETG("w", ADD(VARG("w"), U16(K))); + RzILOpEffect *set_status_op = + SET_STATUS_ADD(VARL("_1"), U16(K), VARG("w")); + return SEQ3(SETL("_1", VARG("w")), + add_op, + set_status_op); +} + +/** + * ADDWF + * Operation: Add freg to wreg. + * Operands: f, d + * Status affected : C, DC, Z + * */ +IL_LIFTER_IMPL(ADDWF) { + RzILOpEffect *add_op = SETG(RWF, ADD(VARG(RW), U16(K))); + RzILOpEffect *set_status_op = + SET_STATUS_ADD(VARL("_1"), U16(K), VARG(RWF)); + return SEQ3(SETL("_1", VARG(RW)), + add_op, + set_status_op); +} + +IL_LIFTER_IMPL(ANDLW) { + // TODO: set status Z + return SETG(RW, LOGAND(VARG(RW), U16(K))); +} + +/** + * ANDWF + * Operation: Take logical AND of freg and wreg. + * Operands: f, d + * Status affected : Z + * */ +IL_LIFTER_IMPL(ANDWF) { + // TODO: set status Z + return SETG(RWF, LOGAND(VARG(RW), U16(K))); +} + +static RzILOpPure *bit_set(RzILOpPure *v, ut32 b, bool x) { + if (x) { + return LOGOR(v, U8(1 << b)); + } + return LOGAND(v, U8(~(1 << b))); +} + +static RzILOpPure *bit_get(RzILOpPure *v, ut32 b) { + return NON_ZERO(LOGAND(v, U8(1 << b))); +} + +static RzILOpEffect *regbit_set(const char *reg, ut32 b, bool x) { + return SETG(reg, bit_set(VARG(reg), b, x)); +} + +IL_LIFTER_IMPL(BCF) { + return regbit_set(pic_midrange_regname(F), B, 0); +} + +IL_LIFTER_IMPL(BSF) { + return regbit_set(pic_midrange_regname(F), B, 1); +} + +IL_LIFTER_IMPL(BTFSC) { + return BRANCH(bit_get(VARG(pic_midrange_regname(F)), B), NOP(), JMP(U32(PC + INS_LEN * 2))); +} + +IL_LIFTER_IMPL(BTFSS) { + return BRANCH(bit_get(VARG(pic_midrange_regname(F)), B), JMP(U32(PC + INS_LEN * 2)), NOP()); +} + +IL_LIFTER_IMPL(CALL) { + return SEQ2( + SETG("tos", U16(PC + INS_LEN)), + JMP(LOGOR(U16(K), SHIFTL0(SLICE(VARG("pclath"), 3, 4), U16(11))))); +} + +IL_LIFTER_IMPL(CLRF) { + return SEQ2( + SETG(pic_midrange_regname(F), U16(0)), + SETG("z", U16(1))); +} + +IL_LIFTER_IMPL(CLR) { + return SEQ2( + SETG(RW, U16(0)), + SETG("z", U16(1))); +} + +IL_LIFTER_IMPL(CLRWDT) { + return SEQ4( + SETG("wdt", U16(0)), + SETG("wdt_prescaler_count", U16(0)), + SETG("to", U16(1)), + SETG("pd", U16(1))); +} + +IL_LIFTER_IMPL(COMF) { + return SEQ2( + SETG(RWF, NEG(VRF)), + SETG("z", IS_ZERO(VARG(RWF)))); +} + +IL_LIFTER_IMPL(DECF) { + return SEQ2( + SETG(RWF, SUB(VRF, U16(1))), + SETG("z", IS_ZERO(VARG(RWF)))); +} + +IL_LIFTER_IMPL(DECFSZ) { + return SEQ2( + SETG(RWF, SUB(VRF, U16(1))), + BRANCH(IS_ZERO(VARG(RWF)), + JMP(U16(PC + INS_LEN * 2)), + NOP())); +} + +IL_LIFTER_IMPL(GOTO) { + return JMP(LOGOR(U16(K), SHIFTL0(SLICE(VARG("pclath"), 3, 4), U16(11)))); +} + +IL_LIFTER_IMPL(INCF) { + return SEQ2( + SETG(RWF, ADD(VRF, U16(1))), + SETG("z", IS_ZERO(VARG(RWF)))); +} + +IL_LIFTER_IMPL(INCFSZ) { + return SEQ2( + SETG(RWF, ADD(VRF, U16(1))), + BRANCH(IS_ZERO(VARG(RWF)), + JMP(U16(PC + INS_LEN * 2)), + NOP())); +} + +IL_LIFTER_IMPL(IORLW) { + return SEQ2( + SETG(RW, LOGOR(VRW, U16(K))), + SETG("z", IS_ZERO(VRW))); +} + +IL_LIFTER_IMPL(IORWF) { + return SEQ2( + SETG(RWF, LOGOR(VRW, VRF)), + SETG("z", IS_ZERO(VRWF))); +} + +IL_LIFTER_IMPL(MOVLW) { + return SETG(RW, U16(K)); +} + +IL_LIFTER_IMPL(MOVF) { + return SEQ2(SETG(RWF, VRF), + SETG("z", IS_ZERO(VRWF))); +} + +IL_LIFTER_IMPL(MOVWF) { + return SETG(RF, VRW); +} + +IL_LIFTER_IMPL(OPTION) { + return SETG("option", VRW); +} + +IL_LIFTER_IMPL(RETFIE) { + return SEQ2( + SETG("tos", VPC), + SETG("gie", U16(1))); +} + +IL_LIFTER_IMPL(RETLW) { + return SEQ2( + SETG(RW, U16(K)), + JMP(VARG("tos"))); +} + +IL_LIFTER_IMPL(RETURN) { + return JMP(VARG("tos")); +} + +IL_LIFTER_IMPL(RLF) { + return SEQ3( + SETG("_c", LOGAND(SHIFTR0(VRF, U8(7)), U8(1))), + SETG(RWF, LOGOR(SHIFTL0(VRF, U8(1)), VARG("c"))), + SETG("c", VARL("_v"))); +} + +IL_LIFTER_IMPL(RRF) { + return SEQ3( + SETG("_c", LOGAND(VRF, U8(1))), + SETG(RWF, LOGOR(SHIFTR0(VRF, U8(1)), SHIFTL0(VARG("c"), U8(7)))), + SETG("c", VARL("_v"))); +} + +IL_LIFTER_IMPL(SLEEP) { + return SEQ4( + SETG("wdt", U8(0)), + SETG("wdt_prescaler_count", U8(0)), + SETG("to", U8(1)), + SETG("pd", U8(0))); +} + +IL_LIFTER_IMPL(SUBLW) { + return SEQ3( + SETL("_w", VRW), + SETG(RW, SUB(U8(K), VARL("_w"))), + SET_STATUS_SUB(VARL("_w"), U8(K), VRW)); +} + +IL_LIFTER_IMPL(SUBWF) { + return SEQ3( + SETL("_res", SUB(VRF, VRW)), + SET_STATUS_SUB(VRF, VRW, VARL("_res")), + SETG(RWF, VARL("_res"))); +} + +IL_LIFTER_IMPL(SWAPF) { + return SETG(RWF, APPEND(UNSIGNED(4, VRF), UNSIGNED(4, SHIFTR0(VRF, U8(4))))); +} + +IL_LIFTER_IMPL(TRIS) { + // TODO: TRIS register f; + return SETG("tris", VRW); +} + +/** + * XORLW. + * Operation: Take logical XOR between literal and wreg + * Operands: Literal (k) + * Status affected : Z + * */ +IL_LIFTER_IMPL(XORLW) { + return SEQ2( + SETG(RW, LOGXOR(VRW, U8(K))), + SETG("z", IS_ZERO(VRW))); +} + +/** + * ANDWF + * Operation: Take logical AND of freg and wreg. + * Operands: f, d + * Status affected : Z + * */ +IL_LIFTER_IMPL(XORWF) { + return SEQ2( + SETG(RWF, LOGXOR(VRW, VRF)), + SETG("z", IS_ZERO(VRWF))); +} + +// 14-bit enhanced PIC additional instructions + +RzILOpEffect *reset() { + return NOP(); +} + +RzILOpEffect *setZ(RzILOpPure *x) { + return SETG("z", IS_ZERO(x)); +} + +IL_LIFTER_IMPL(RESET) { + return SEQ2( + reset(), + JMP(U16(0))); +} +IL_LIFTER_IMPL(CALLW) { + return SEQ2( + SETG("tos", U16(PC + INS_LEN)), + JMP(LOGOR(U16(K), UNSIGNED(16, VRW)))); +} +IL_LIFTER_IMPL(BRW) { + return JMP(ADD(UNSIGNED(16, VRW), SHIFTR0(U16(PC + INS_LEN), U16(1)))); +} +IL_LIFTER_IMPL(MOVIW_1) { + switch (ctx->d & 0b11) { + case 0x0: return SEQ3( + SETG(RFSR(N), ADD(VRFSR(N), U8(1))), + SETG(RW, VRFSR(N)), + setZ(VRW)); + case 0x1: return SEQ3( + SETG(RFSR(N), SUB(VRFSR(N), U8(1))), + SETG(RW, VRFSR(N)), + setZ(VRW)); + case 0x2: return SEQ3( + SETG(RW, VRFSR(N)), + SETG(RFSR(N), ADD(VRFSR(N), U8(1))), + setZ(VRW)); + case 0x3: return SEQ3( + SETG(RW, VRFSR(N)), + SETG(RFSR(N), SUB(VRFSR(N), U8(1))), + setZ(VRW)); + default: break; + } + return NULL; +} +IL_LIFTER_IMPL(MOVIW_2) { + return SEQ2( + SETG(RW, LOAD(ADD(VRFSR(N), S8(SEXT(8, K, 6))))), + setZ(VRW)); +} + +IL_LIFTER_IMPL(MOVWI_1) { + return SETG(RFSR(N), VRW); +} +IL_LIFTER_IMPL(MOVWI_2) { + return STORE(ADD(VRFSR(N), S8(SEXT(8, K, 6))), VRW); +} + +IL_LIFTER_IMPL(MOVLB) { + // imm5? + return SETG("bsr", U8(K)); +} +IL_LIFTER_IMPL(MOVLP) { + // imm7? + return SETG("pclath", U8(K)); +} + +IL_LIFTER_IMPL(LSLF) { + return SEQ3( + SETG("c", MSB(VRF)), + SETG(RWF, SHIFTL0(VRF, U8(1))), + setZ(VRWF)); +} +IL_LIFTER_IMPL(LSRF) { + return SEQ3( + SETG("c", LSB(VRF)), + SETG(RWF, SHIFTR0(VRF, U8(1))), + setZ(VRWF)); +} +IL_LIFTER_IMPL(ASRF) { + return SEQ3( + SETG("c", LSB(VRF)), + SETG(RWF, SHIFTRA(VRF, U8(1))), + setZ(VRWF)); +} +IL_LIFTER_IMPL(SUBWFB) { + return SEQ3( + SETG("_res", ADD(SUB(VRF, VRW), VARG("c"))), + SET_STATUS_SUB(VRF, VRW, VARL("_res")), + SETG(RWF, VARL("_res"))); +} +IL_LIFTER_IMPL(ADDWFC) { + return SEQ3( + SETG("_res", ADD(ADD(VRF, VRW), VARG("c"))), + SET_STATUS_ADD(VRF, VRW, VARL("_res")), + SETG(RWF, VARL("_res"))); +} +IL_LIFTER_IMPL(ADDFSR) { + return SETG(RFSR(N), ADD(VRFSR(N), S8(SEXT(8, K, 6)))); +} +IL_LIFTER_IMPL(BRA) { + return JMP(U16(PC + SEXT(16, K, 9))); +} + +/** + * Create new Mid-Range device CPU state. + * + * */ +RZ_IPI bool rz_pic_midrange_cpu_state_setup( + PicMidrangeCPUState *state, + PicMidrangeDeviceType device_type) { + rz_return_val_if_fail(state, NULL); + if (device_type >= PIC_MIDRANGE_SUPPORTED_DEVICE_NUM) { + RZ_LOG_ERROR("RzIL : Invalid PIC Mid-Range device type provided"); + return false; + } + + state->device_type = device_type; + state->selected_bank = 0; // initially bank is 0 + state->selected_page = 0; // initially page is 0 + return true; +} + +/** + * \brief Returns IL VM config for given PIC Mid-Range device type. + * + * \param analysis \c RzAnalysis instance. + * \param device_type Device type in PIC16F family. + * + * \return valid ptr to RzAnalysisILConfig on success, NULL otherwise. + * */ +RZ_IPI RzAnalysisILConfig *rz_midrange_il_vm_config(RZ_NONNULL RzAnalysis *analysis, PicMidrangeDeviceType device_type) { + return NULL; +} \ No newline at end of file