13fa28dd6SMichael Rolnik /* 23fa28dd6SMichael Rolnik * QEMU AVR CPU 33fa28dd6SMichael Rolnik * 43fa28dd6SMichael Rolnik * Copyright (c) 2016-2020 Michael Rolnik 53fa28dd6SMichael Rolnik * 63fa28dd6SMichael Rolnik * This library is free software; you can redistribute it and/or 73fa28dd6SMichael Rolnik * modify it under the terms of the GNU Lesser General Public 83fa28dd6SMichael Rolnik * License as published by the Free Software Foundation; either 93fa28dd6SMichael Rolnik * version 2.1 of the License, or (at your option) any later version. 103fa28dd6SMichael Rolnik * 113fa28dd6SMichael Rolnik * This library is distributed in the hope that it will be useful, 123fa28dd6SMichael Rolnik * but WITHOUT ANY WARRANTY; without even the implied warranty of 133fa28dd6SMichael Rolnik * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 143fa28dd6SMichael Rolnik * Lesser General Public License for more details. 153fa28dd6SMichael Rolnik * 163fa28dd6SMichael Rolnik * You should have received a copy of the GNU Lesser General Public 173fa28dd6SMichael Rolnik * License along with this library; if not, see 183fa28dd6SMichael Rolnik * <http://www.gnu.org/licenses/lgpl-2.1.html> 193fa28dd6SMichael Rolnik */ 203fa28dd6SMichael Rolnik 213fa28dd6SMichael Rolnik #include "qemu/osdep.h" 223fa28dd6SMichael Rolnik #include "cpu.h" 233fa28dd6SMichael Rolnik #include "migration/cpu.h" 243fa28dd6SMichael Rolnik 253fa28dd6SMichael Rolnik static int get_sreg(QEMUFile *f, void *opaque, size_t size, 263fa28dd6SMichael Rolnik const VMStateField *field) 273fa28dd6SMichael Rolnik { 283fa28dd6SMichael Rolnik CPUAVRState *env = opaque; 293fa28dd6SMichael Rolnik uint8_t sreg; 303fa28dd6SMichael Rolnik 313fa28dd6SMichael Rolnik sreg = qemu_get_byte(f); 323fa28dd6SMichael Rolnik cpu_set_sreg(env, sreg); 333fa28dd6SMichael Rolnik return 0; 343fa28dd6SMichael Rolnik } 353fa28dd6SMichael Rolnik 363fa28dd6SMichael Rolnik static int put_sreg(QEMUFile *f, void *opaque, size_t size, 373ddba9a9SMarkus Armbruster const VMStateField *field, JSONWriter *vmdesc) 383fa28dd6SMichael Rolnik { 393fa28dd6SMichael Rolnik CPUAVRState *env = opaque; 403fa28dd6SMichael Rolnik uint8_t sreg = cpu_get_sreg(env); 413fa28dd6SMichael Rolnik 423fa28dd6SMichael Rolnik qemu_put_byte(f, sreg); 433fa28dd6SMichael Rolnik return 0; 443fa28dd6SMichael Rolnik } 453fa28dd6SMichael Rolnik 463fa28dd6SMichael Rolnik static const VMStateInfo vms_sreg = { 473fa28dd6SMichael Rolnik .name = "sreg", 483fa28dd6SMichael Rolnik .get = get_sreg, 493fa28dd6SMichael Rolnik .put = put_sreg, 503fa28dd6SMichael Rolnik }; 513fa28dd6SMichael Rolnik 523fa28dd6SMichael Rolnik static int get_segment(QEMUFile *f, void *opaque, size_t size, 533fa28dd6SMichael Rolnik const VMStateField *field) 543fa28dd6SMichael Rolnik { 553fa28dd6SMichael Rolnik uint32_t *ramp = opaque; 563fa28dd6SMichael Rolnik uint8_t temp; 573fa28dd6SMichael Rolnik 583fa28dd6SMichael Rolnik temp = qemu_get_byte(f); 593fa28dd6SMichael Rolnik *ramp = ((uint32_t)temp) << 16; 603fa28dd6SMichael Rolnik return 0; 613fa28dd6SMichael Rolnik } 623fa28dd6SMichael Rolnik 633fa28dd6SMichael Rolnik static int put_segment(QEMUFile *f, void *opaque, size_t size, 643ddba9a9SMarkus Armbruster const VMStateField *field, JSONWriter *vmdesc) 653fa28dd6SMichael Rolnik { 663fa28dd6SMichael Rolnik uint32_t *ramp = opaque; 673fa28dd6SMichael Rolnik uint8_t temp = *ramp >> 16; 683fa28dd6SMichael Rolnik 693fa28dd6SMichael Rolnik qemu_put_byte(f, temp); 703fa28dd6SMichael Rolnik return 0; 713fa28dd6SMichael Rolnik } 723fa28dd6SMichael Rolnik 733fa28dd6SMichael Rolnik static const VMStateInfo vms_rampD = { 743fa28dd6SMichael Rolnik .name = "rampD", 753fa28dd6SMichael Rolnik .get = get_segment, 763fa28dd6SMichael Rolnik .put = put_segment, 773fa28dd6SMichael Rolnik }; 783fa28dd6SMichael Rolnik static const VMStateInfo vms_rampX = { 793fa28dd6SMichael Rolnik .name = "rampX", 803fa28dd6SMichael Rolnik .get = get_segment, 813fa28dd6SMichael Rolnik .put = put_segment, 823fa28dd6SMichael Rolnik }; 833fa28dd6SMichael Rolnik static const VMStateInfo vms_rampY = { 843fa28dd6SMichael Rolnik .name = "rampY", 853fa28dd6SMichael Rolnik .get = get_segment, 863fa28dd6SMichael Rolnik .put = put_segment, 873fa28dd6SMichael Rolnik }; 883fa28dd6SMichael Rolnik static const VMStateInfo vms_rampZ = { 893fa28dd6SMichael Rolnik .name = "rampZ", 903fa28dd6SMichael Rolnik .get = get_segment, 913fa28dd6SMichael Rolnik .put = put_segment, 923fa28dd6SMichael Rolnik }; 933fa28dd6SMichael Rolnik static const VMStateInfo vms_eind = { 943fa28dd6SMichael Rolnik .name = "eind", 953fa28dd6SMichael Rolnik .get = get_segment, 963fa28dd6SMichael Rolnik .put = put_segment, 973fa28dd6SMichael Rolnik }; 983fa28dd6SMichael Rolnik 993fa28dd6SMichael Rolnik const VMStateDescription vms_avr_cpu = { 1003fa28dd6SMichael Rolnik .name = "cpu", 101*c2cf139dSPhilippe Mathieu-Daudé .version_id = 1, 102*c2cf139dSPhilippe Mathieu-Daudé .minimum_version_id = 1, 1033fa28dd6SMichael Rolnik .fields = (VMStateField[]) { 1043fa28dd6SMichael Rolnik VMSTATE_UINT32(env.pc_w, AVRCPU), 1053fa28dd6SMichael Rolnik VMSTATE_UINT32(env.sp, AVRCPU), 1063fa28dd6SMichael Rolnik VMSTATE_UINT32(env.skip, AVRCPU), 1073fa28dd6SMichael Rolnik 1083fa28dd6SMichael Rolnik VMSTATE_UINT32_ARRAY(env.r, AVRCPU, NUMBER_OF_CPU_REGISTERS), 1093fa28dd6SMichael Rolnik 1103fa28dd6SMichael Rolnik VMSTATE_SINGLE(env, AVRCPU, 0, vms_sreg, CPUAVRState), 1113fa28dd6SMichael Rolnik VMSTATE_SINGLE(env.rampD, AVRCPU, 0, vms_rampD, uint32_t), 1123fa28dd6SMichael Rolnik VMSTATE_SINGLE(env.rampX, AVRCPU, 0, vms_rampX, uint32_t), 1133fa28dd6SMichael Rolnik VMSTATE_SINGLE(env.rampY, AVRCPU, 0, vms_rampY, uint32_t), 1143fa28dd6SMichael Rolnik VMSTATE_SINGLE(env.rampZ, AVRCPU, 0, vms_rampZ, uint32_t), 1153fa28dd6SMichael Rolnik VMSTATE_SINGLE(env.eind, AVRCPU, 0, vms_eind, uint32_t), 1163fa28dd6SMichael Rolnik 1173fa28dd6SMichael Rolnik VMSTATE_END_OF_LIST() 1183fa28dd6SMichael Rolnik } 1193fa28dd6SMichael Rolnik }; 120