MCPcopy Create free account
hub / github.com/LPC4/Full-Stack / handle_atomic

Function handle_atomic

crates/virtual-machine/src/cpu/pipeline/memory.rs:349–404  ·  view source on GitHub ↗
(
    bus: &mut SystemBus,
    reservation: &mut Option<u64>,
    funct5: u8,
    funct3: u8,
    rd: usize,
    addr: u64,
    val: u64,
)

Source from the content-addressed store, hash-verified

347 .map_err(|_| VmError::LoadAccessFault(addr))?;
348 (w as i32) as i64 as u64
349 } else {
350 bus.read_doubleword(addr)
351 .map_err(|_| VmError::LoadAccessFault(addr))?
352 };
353 Ok(result)
354 }
355 // SC
356 0x03 => {
357 if *reservation == Some(addr) {
358 *reservation = None;
359 if is_word {
360 bus.write_word(addr, val as u32)
361 .map_err(|_| VmError::StoreAccessFault(addr))?;
362 } else {
363 bus.write_doubleword(addr, val)
364 .map_err(|_| VmError::StoreAccessFault(addr))?;
365 }
366 Ok(0) // success
367 } else {
368 Ok(1) // failure
369 }
370 }
371 // AMOs
372 _ => {
373 // Suppress unused rd warning, it's used by the caller
374 let _ = rd;
375 amo_op(bus, funct5, funct3, addr, val)
376 }
377 }
378}
379
380fn amo_op(
381 bus: &mut SystemBus,
382 funct5: u8,
383 funct3: u8,
384 addr: u64,
385 val: u64,
386) -> Result<u64, VmError> {
387 let is_word = funct3 == 2;
388
389 if is_word {
390 // 32-bit AMO
391 let old_w = bus
392 .read_word(addr)
393 .map_err(|_| VmError::LoadAccessFault(addr))?;
394 let old_i = old_w as i32;
395 let val_i = val as i32;
396
397 let new_i: i32 = match funct5 {
398 0x00 => old_i.wrapping_add(val_i), // AMOADD.W
399 0x01 => val_i, // AMOSWAP.W
400 0x04 => old_i ^ val_i, // AMOXOR.W
401 0x08 => old_i | val_i, // AMOOR.W
402 0x0C => old_i & val_i, // AMOAND.W
403 0x10 => old_i.min(val_i), // AMOMIN.W
404 0x14 => old_i.max(val_i), // AMOMAX.W
405 0x18 => {
406 let old_u = old_w;

Callers 1

memory_stage_with_pmpFunction · 0.85

Calls 5

amo_opFunction · 0.85
read_wordMethod · 0.45
read_doublewordMethod · 0.45
write_wordMethod · 0.45
write_doublewordMethod · 0.45

Tested by

no test coverage detected